otpilot 2.3.0__tar.gz → 2.3.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. {otpilot-2.3.0/otpilot.egg-info → otpilot-2.3.2}/PKG-INFO +118 -4
  2. otpilot-2.3.2/README.md +8 -0
  3. {otpilot-2.3.0 → otpilot-2.3.2}/docs/README.md +115 -2
  4. {otpilot-2.3.0 → otpilot-2.3.2}/otpilot/__init__.py +1 -1
  5. {otpilot-2.3.0 → otpilot-2.3.2}/otpilot/config.py +4 -0
  6. {otpilot-2.3.0 → otpilot-2.3.2}/otpilot/gmail_client.py +306 -4
  7. {otpilot-2.3.0 → otpilot-2.3.2}/otpilot/main.py +3 -2
  8. {otpilot-2.3.0 → otpilot-2.3.2}/otpilot/setup_wizard.py +121 -6
  9. {otpilot-2.3.0 → otpilot-2.3.2}/otpilot/token_store.py +59 -1
  10. {otpilot-2.3.0 → otpilot-2.3.2/otpilot.egg-info}/PKG-INFO +118 -4
  11. {otpilot-2.3.0 → otpilot-2.3.2}/otpilot.egg-info/requires.txt +1 -0
  12. {otpilot-2.3.0 → otpilot-2.3.2}/pyproject.toml +1 -0
  13. {otpilot-2.3.0 → otpilot-2.3.2}/setup.py +4 -3
  14. {otpilot-2.3.0 → otpilot-2.3.2}/tests/test_main.py +25 -10
  15. otpilot-2.3.0/README.md +0 -3
  16. {otpilot-2.3.0 → otpilot-2.3.2}/LICENSE +0 -0
  17. {otpilot-2.3.0 → otpilot-2.3.2}/otpilot/clipboard.py +0 -0
  18. {otpilot-2.3.0 → otpilot-2.3.2}/otpilot/history.py +0 -0
  19. {otpilot-2.3.0 → otpilot-2.3.2}/otpilot/hotkey_listener.py +0 -0
  20. {otpilot-2.3.0 → otpilot-2.3.2}/otpilot/logger.py +0 -0
  21. {otpilot-2.3.0 → otpilot-2.3.2}/otpilot/notifier.py +0 -0
  22. {otpilot-2.3.0 → otpilot-2.3.2}/otpilot/otp_extractor.py +0 -0
  23. {otpilot-2.3.0 → otpilot-2.3.2}/otpilot/tray.py +0 -0
  24. {otpilot-2.3.0 → otpilot-2.3.2}/otpilot.egg-info/SOURCES.txt +0 -0
  25. {otpilot-2.3.0 → otpilot-2.3.2}/otpilot.egg-info/dependency_links.txt +0 -0
  26. {otpilot-2.3.0 → otpilot-2.3.2}/otpilot.egg-info/entry_points.txt +0 -0
  27. {otpilot-2.3.0 → otpilot-2.3.2}/otpilot.egg-info/top_level.txt +0 -0
  28. {otpilot-2.3.0 → otpilot-2.3.2}/setup.cfg +0 -0
  29. {otpilot-2.3.0 → otpilot-2.3.2}/tests/test_clipboard.py +0 -0
  30. {otpilot-2.3.0 → otpilot-2.3.2}/tests/test_config.py +0 -0
  31. {otpilot-2.3.0 → otpilot-2.3.2}/tests/test_gmail_client.py +0 -0
  32. {otpilot-2.3.0 → otpilot-2.3.2}/tests/test_history.py +0 -0
  33. {otpilot-2.3.0 → otpilot-2.3.2}/tests/test_logger.py +0 -0
  34. {otpilot-2.3.0 → otpilot-2.3.2}/tests/test_notifier.py +0 -0
  35. {otpilot-2.3.0 → otpilot-2.3.2}/tests/test_otp_extractor.py +0 -0
  36. {otpilot-2.3.0 → otpilot-2.3.2}/tests/test_token_store.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: otpilot
3
- Version: 2.3.0
3
+ Version: 2.3.2
4
4
  Summary: Background CLI utility that copies OTPs from Gmail to clipboard on hotkey trigger
5
5
  Author: Jenil
6
6
  Author-email: Jenil <mail2jenil.pokar19@gmail.com>
@@ -43,13 +43,14 @@ Classifier: Programming Language :: Python :: 3.13
43
43
  Classifier: Programming Language :: Python :: 3.14
44
44
  Classifier: Topic :: Communications :: Email
45
45
  Classifier: Topic :: Utilities
46
- Requires-Python: >=3.8
46
+ Requires-Python: >=3.10
47
47
  Description-Content-Type: text/markdown
48
48
  License-File: LICENSE
49
49
  Requires-Dist: requests>=2.31.0
50
50
  Requires-Dist: packaging>=23.0
51
51
  Requires-Dist: google-api-python-client>=2.100.0
52
52
  Requires-Dist: google-auth>=2.23.0
53
+ Requires-Dist: google-auth-oauthlib>=1.2.0
53
54
  Requires-Dist: pynput>=1.7.6
54
55
  Requires-Dist: pystray>=0.19.5
55
56
  Requires-Dist: Pillow>=10.0.0
@@ -129,7 +130,7 @@ otpilot setup
129
130
  ```
130
131
 
131
132
  The wizard will:
132
- - Open your browser for a one-time Google sign-in (read-only Gmail access)
133
+ - Let you choose one of 3 authentication modes (Firebase, credentials.json, or IMAP App Password)
133
134
  - Let you configure hotkey, notifications, and scan preferences
134
135
  - Save everything locally
135
136
 
@@ -149,6 +150,105 @@ OTPilot runs in the background with a system tray icon when supported.
149
150
 
150
151
  ---
151
152
 
153
+ ## Authentication Modes
154
+
155
+ OTPilot supports 3 authentication modes. Choose one during `otpilot setup`.
156
+
157
+ ## Setup Responsibilities (You vs End Users)
158
+
159
+ Use this quick split to know what *you* (OTPilot deployer/maintainer) must set up once, versus what each *end user* must do locally.
160
+
161
+ ### If you provide Firebase hosted auth
162
+
163
+ **You (maintainer) set up once:**
164
+ - Build/deploy the web auth page (for example `https://jenil-otpilot.vercel.app/auth`)
165
+ - Configure Firebase project + Google sign-in
166
+ - Add authorized domains in Firebase Auth (`jenil-otpilot.vercel.app`, `localhost`)
167
+ - Set web env vars (`NEXT_PUBLIC_FIREBASE_API_KEY`, `NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN`, `NEXT_PUBLIC_FIREBASE_PROJECT_ID`)
168
+ - Ensure linked Google Cloud project has Gmail API enabled and consent screen configured for `gmail.readonly`
169
+
170
+ **Each user sets up locally:**
171
+ - Install OTPilot (`pip install otpilot`)
172
+ - Run `otpilot setup`
173
+ - Choose **[1] Firebase Auth**
174
+ - Paste your hosted auth page URL when prompted
175
+ - Complete Google sign-in in browser
176
+
177
+ ### If users bring their own OAuth client (`credentials.json`)
178
+
179
+ **You (maintainer) set up:**
180
+ - Nothing required for hosted auth
181
+
182
+ **Each user sets up locally:**
183
+ - Create their own Google Cloud project + OAuth client
184
+ - Enable Gmail API on that project
185
+ - Download `credentials.json` and place at `~/.otpilot/credentials.json`
186
+ - Run `otpilot setup` and choose **[2] My own credentials.json**
187
+
188
+ ### If users use Gmail App Password (IMAP)
189
+
190
+ **You (maintainer) set up:**
191
+ - Nothing required for hosted auth
192
+
193
+ **Each user sets up locally:**
194
+ - Enable 2-Step Verification on Gmail account
195
+ - Generate Gmail App Password at `https://myaccount.google.com/apppasswords`
196
+ - Run `otpilot setup` and choose **[3] Gmail App Password**
197
+ - Enter Gmail address + app password
198
+
199
+ ---
200
+
201
+ ### Mode 1: Firebase Auth (Recommended)
202
+
203
+ Use this when you have a hosted Firebase web auth page that performs Google sign-in and redirects back to OTPilot.
204
+
205
+ **You need:**
206
+ - A Firebase web page URL that:
207
+ - Requests Gmail readonly scope (`https://www.googleapis.com/auth/gmail.readonly`)
208
+ - Retrieves `accessToken` and `refreshToken`
209
+ - Redirects to the provided local `redirect_uri` with query params:
210
+ - `access_token`
211
+ - `refresh_token` (if available)
212
+ - `expires_at` (unix timestamp, if available)
213
+
214
+ **Setup flow:**
215
+ 1. Run `otpilot setup`
216
+ 2. Choose **[1] Firebase Auth**
217
+ 3. Enter your Firebase auth page URL when prompted
218
+ 4. Complete browser sign-in
219
+
220
+ ### Mode 2: My own `credentials.json`
221
+
222
+ Use this when you want your own Google Cloud OAuth client.
223
+
224
+ **You need:**
225
+ - A Google Cloud project with Gmail API enabled
226
+ - OAuth client credentials downloaded as `credentials.json`
227
+ - File placed at: `~/.otpilot/credentials.json`
228
+
229
+ **Setup flow:**
230
+ 1. Run `otpilot setup`
231
+ 2. Choose **[2] My own credentials.json**
232
+ 3. Confirm once `~/.otpilot/credentials.json` exists
233
+ 4. Complete browser sign-in
234
+
235
+ ### Mode 3: Gmail App Password (IMAP)
236
+
237
+ Use this when you prefer no OAuth flow inside OTPilot.
238
+
239
+ **You need:**
240
+ - A Gmail account with 2-Step Verification enabled
241
+ - A Gmail App Password from:
242
+ - https://myaccount.google.com/apppasswords
243
+
244
+ **Setup flow:**
245
+ 1. Run `otpilot setup`
246
+ 2. Choose **[3] Gmail App Password**
247
+ 3. Enter your Gmail address
248
+ 4. Enter your App Password
249
+
250
+ ---
251
+
152
252
  ## CLI Commands
153
253
 
154
254
  | Command | Description |
@@ -174,6 +274,7 @@ OTPilot stores its configuration at `~/.otpilot/config.json`:
174
274
 
175
275
  ```json
176
276
  {
277
+ "auth_mode": "firebase",
177
278
  "hotkey": "ctrl+shift+o",
178
279
  "notify_on_copy": true,
179
280
  "otp_max_age_minutes": 10,
@@ -183,12 +284,18 @@ OTPilot stores its configuration at `~/.otpilot/config.json`:
183
284
  "auto_start_on_boot": false,
184
285
  "notification_sound": false,
185
286
  "mask_otp_in_notification": true,
186
- "check_updates_on_start": true
287
+ "check_updates_on_start": true,
288
+ "setup_complete": true,
289
+ "firebase_web_url": "",
290
+ "imap_user": "",
291
+ "imap_host": "imap.gmail.com",
292
+ "imap_port": 993
187
293
  }
188
294
  ```
189
295
 
190
296
  | Field | Type | Default | Description |
191
297
  | -------------------------- | ------ | -------------- | ------------------------------------------------- |
298
+ | `auth_mode` | string | `firebase` | Auth backend: `firebase`, `credentials`, or `imap` |
192
299
  | `hotkey` | string | `ctrl+shift+o` | Global hotkey combination |
193
300
  | `notify_on_copy` | bool | `true` | Show desktop notification when OTP is copied |
194
301
  | `otp_max_age_minutes` | int | `10` | Ignore emails older than this (minutes) |
@@ -199,6 +306,11 @@ OTPilot stores its configuration at `~/.otpilot/config.json`:
199
306
  | `notification_sound` | bool | `false` | Play a sound with notifications |
200
307
  | `mask_otp_in_notification` | bool | `true` | Mask middle digits in notification (e.g. 84••93) |
201
308
  | `check_updates_on_start` | bool | `true` | Check PyPI for a newer version on startup |
309
+ | `setup_complete` | bool | `false` | Indicates setup has been completed |
310
+ | `firebase_web_url` | string | `""` | URL of your hosted Firebase auth page |
311
+ | `imap_user` | string | `""` | Gmail address used for IMAP mode |
312
+ | `imap_host` | string | `imap.gmail.com` | IMAP host for app-password mode |
313
+ | `imap_port` | int | `993` | IMAP SSL port |
202
314
 
203
315
  ### Files Stored Locally
204
316
 
@@ -210,6 +322,7 @@ OTPilot stores its configuration at `~/.otpilot/config.json`:
210
322
  | `~/.otpilot/otpilot.pid` | PID of the running background process |
211
323
  | System keyring (`otpilot`) | Preferred OAuth token storage |
212
324
  | `~/.otpilot/token.json` | Fallback token storage |
325
+ | `~/.otpilot/app_password.txt` | Fallback IMAP app-password storage |
213
326
 
214
327
  ---
215
328
 
@@ -269,6 +382,7 @@ OTPilot scans the subject line and body of your recent emails for:
269
382
  | Issue | Solution |
270
383
  | ----------------------------- | --------------------------------------------------------------- |
271
384
  | "Not authenticated" error | Run `otpilot setup` to re-authenticate |
385
+ | "Access token expired..." | Use Firebase/credentials mode with refresh token, or switch to IMAP App Password in setup |
272
386
  | No OTP found | Check `otp_max_age_minutes` — the email might be too old |
273
387
  | Clipboard not working (Linux) | Install `xclip`: `sudo apt install xclip` |
274
388
  | Hotkey not working | Run `otpilot hotkey` to reconfigure |
@@ -0,0 +1,8 @@
1
+ # OTPilot
2
+
3
+ Project documentation lives in [`docs/README.md`](docs/README.md).
4
+
5
+ Authentication modes are documented there, including setup for:
6
+ - Firebase hosted OAuth page
7
+ - Your own Google `credentials.json`
8
+ - Gmail App Password (IMAP)
@@ -61,7 +61,7 @@ otpilot setup
61
61
  ```
62
62
 
63
63
  The wizard will:
64
- - Open your browser for a one-time Google sign-in (read-only Gmail access)
64
+ - Let you choose one of 3 authentication modes (Firebase, credentials.json, or IMAP App Password)
65
65
  - Let you configure hotkey, notifications, and scan preferences
66
66
  - Save everything locally
67
67
 
@@ -81,6 +81,105 @@ OTPilot runs in the background with a system tray icon when supported.
81
81
 
82
82
  ---
83
83
 
84
+ ## Authentication Modes
85
+
86
+ OTPilot supports 3 authentication modes. Choose one during `otpilot setup`.
87
+
88
+ ## Setup Responsibilities (You vs End Users)
89
+
90
+ Use this quick split to know what *you* (OTPilot deployer/maintainer) must set up once, versus what each *end user* must do locally.
91
+
92
+ ### If you provide Firebase hosted auth
93
+
94
+ **You (maintainer) set up once:**
95
+ - Build/deploy the web auth page (for example `https://jenil-otpilot.vercel.app/auth`)
96
+ - Configure Firebase project + Google sign-in
97
+ - Add authorized domains in Firebase Auth (`jenil-otpilot.vercel.app`, `localhost`)
98
+ - Set web env vars (`NEXT_PUBLIC_FIREBASE_API_KEY`, `NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN`, `NEXT_PUBLIC_FIREBASE_PROJECT_ID`)
99
+ - Ensure linked Google Cloud project has Gmail API enabled and consent screen configured for `gmail.readonly`
100
+
101
+ **Each user sets up locally:**
102
+ - Install OTPilot (`pip install otpilot`)
103
+ - Run `otpilot setup`
104
+ - Choose **[1] Firebase Auth**
105
+ - Paste your hosted auth page URL when prompted
106
+ - Complete Google sign-in in browser
107
+
108
+ ### If users bring their own OAuth client (`credentials.json`)
109
+
110
+ **You (maintainer) set up:**
111
+ - Nothing required for hosted auth
112
+
113
+ **Each user sets up locally:**
114
+ - Create their own Google Cloud project + OAuth client
115
+ - Enable Gmail API on that project
116
+ - Download `credentials.json` and place at `~/.otpilot/credentials.json`
117
+ - Run `otpilot setup` and choose **[2] My own credentials.json**
118
+
119
+ ### If users use Gmail App Password (IMAP)
120
+
121
+ **You (maintainer) set up:**
122
+ - Nothing required for hosted auth
123
+
124
+ **Each user sets up locally:**
125
+ - Enable 2-Step Verification on Gmail account
126
+ - Generate Gmail App Password at `https://myaccount.google.com/apppasswords`
127
+ - Run `otpilot setup` and choose **[3] Gmail App Password**
128
+ - Enter Gmail address + app password
129
+
130
+ ---
131
+
132
+ ### Mode 1: Firebase Auth (Recommended)
133
+
134
+ Use this when you have a hosted Firebase web auth page that performs Google sign-in and redirects back to OTPilot.
135
+
136
+ **You need:**
137
+ - A Firebase web page URL that:
138
+ - Requests Gmail readonly scope (`https://www.googleapis.com/auth/gmail.readonly`)
139
+ - Retrieves `accessToken` and `refreshToken`
140
+ - Redirects to the provided local `redirect_uri` with query params:
141
+ - `access_token`
142
+ - `refresh_token` (if available)
143
+ - `expires_at` (unix timestamp, if available)
144
+
145
+ **Setup flow:**
146
+ 1. Run `otpilot setup`
147
+ 2. Choose **[1] Firebase Auth**
148
+ 3. Enter your Firebase auth page URL when prompted
149
+ 4. Complete browser sign-in
150
+
151
+ ### Mode 2: My own `credentials.json`
152
+
153
+ Use this when you want your own Google Cloud OAuth client.
154
+
155
+ **You need:**
156
+ - A Google Cloud project with Gmail API enabled
157
+ - OAuth client credentials downloaded as `credentials.json`
158
+ - File placed at: `~/.otpilot/credentials.json`
159
+
160
+ **Setup flow:**
161
+ 1. Run `otpilot setup`
162
+ 2. Choose **[2] My own credentials.json**
163
+ 3. Confirm once `~/.otpilot/credentials.json` exists
164
+ 4. Complete browser sign-in
165
+
166
+ ### Mode 3: Gmail App Password (IMAP)
167
+
168
+ Use this when you prefer no OAuth flow inside OTPilot.
169
+
170
+ **You need:**
171
+ - A Gmail account with 2-Step Verification enabled
172
+ - A Gmail App Password from:
173
+ - https://myaccount.google.com/apppasswords
174
+
175
+ **Setup flow:**
176
+ 1. Run `otpilot setup`
177
+ 2. Choose **[3] Gmail App Password**
178
+ 3. Enter your Gmail address
179
+ 4. Enter your App Password
180
+
181
+ ---
182
+
84
183
  ## CLI Commands
85
184
 
86
185
  | Command | Description |
@@ -106,6 +205,7 @@ OTPilot stores its configuration at `~/.otpilot/config.json`:
106
205
 
107
206
  ```json
108
207
  {
208
+ "auth_mode": "firebase",
109
209
  "hotkey": "ctrl+shift+o",
110
210
  "notify_on_copy": true,
111
211
  "otp_max_age_minutes": 10,
@@ -115,12 +215,18 @@ OTPilot stores its configuration at `~/.otpilot/config.json`:
115
215
  "auto_start_on_boot": false,
116
216
  "notification_sound": false,
117
217
  "mask_otp_in_notification": true,
118
- "check_updates_on_start": true
218
+ "check_updates_on_start": true,
219
+ "setup_complete": true,
220
+ "firebase_web_url": "",
221
+ "imap_user": "",
222
+ "imap_host": "imap.gmail.com",
223
+ "imap_port": 993
119
224
  }
120
225
  ```
121
226
 
122
227
  | Field | Type | Default | Description |
123
228
  | -------------------------- | ------ | -------------- | ------------------------------------------------- |
229
+ | `auth_mode` | string | `firebase` | Auth backend: `firebase`, `credentials`, or `imap` |
124
230
  | `hotkey` | string | `ctrl+shift+o` | Global hotkey combination |
125
231
  | `notify_on_copy` | bool | `true` | Show desktop notification when OTP is copied |
126
232
  | `otp_max_age_minutes` | int | `10` | Ignore emails older than this (minutes) |
@@ -131,6 +237,11 @@ OTPilot stores its configuration at `~/.otpilot/config.json`:
131
237
  | `notification_sound` | bool | `false` | Play a sound with notifications |
132
238
  | `mask_otp_in_notification` | bool | `true` | Mask middle digits in notification (e.g. 84••93) |
133
239
  | `check_updates_on_start` | bool | `true` | Check PyPI for a newer version on startup |
240
+ | `setup_complete` | bool | `false` | Indicates setup has been completed |
241
+ | `firebase_web_url` | string | `""` | URL of your hosted Firebase auth page |
242
+ | `imap_user` | string | `""` | Gmail address used for IMAP mode |
243
+ | `imap_host` | string | `imap.gmail.com` | IMAP host for app-password mode |
244
+ | `imap_port` | int | `993` | IMAP SSL port |
134
245
 
135
246
  ### Files Stored Locally
136
247
 
@@ -142,6 +253,7 @@ OTPilot stores its configuration at `~/.otpilot/config.json`:
142
253
  | `~/.otpilot/otpilot.pid` | PID of the running background process |
143
254
  | System keyring (`otpilot`) | Preferred OAuth token storage |
144
255
  | `~/.otpilot/token.json` | Fallback token storage |
256
+ | `~/.otpilot/app_password.txt` | Fallback IMAP app-password storage |
145
257
 
146
258
  ---
147
259
 
@@ -201,6 +313,7 @@ OTPilot scans the subject line and body of your recent emails for:
201
313
  | Issue | Solution |
202
314
  | ----------------------------- | --------------------------------------------------------------- |
203
315
  | "Not authenticated" error | Run `otpilot setup` to re-authenticate |
316
+ | "Access token expired..." | Use Firebase/credentials mode with refresh token, or switch to IMAP App Password in setup |
204
317
  | No OTP found | Check `otp_max_age_minutes` — the email might be too old |
205
318
  | Clipboard not working (Linux) | Install `xclip`: `sudo apt install xclip` |
206
319
  | Hotkey not working | Run `otpilot hotkey` to reconfigure |
@@ -10,5 +10,5 @@ Key exports:
10
10
  __app_name__: Human-readable application name.
11
11
  """
12
12
 
13
- __version__ = "2.3.0"
13
+ __version__ = "2.3.2"
14
14
  __app_name__ = "OTPilot"
@@ -24,6 +24,7 @@ TOKEN_FILE: Path = CONFIG_DIR / "token.json"
24
24
 
25
25
  # Default configuration values used for first run and missing keys.
26
26
  DEFAULT_CONFIG: Dict[str, Any] = {
27
+ "auth_mode": "firebase",
27
28
  "hotkey": "ctrl+shift+o",
28
29
  "notify_on_copy": True,
29
30
  "otp_max_age_minutes": 10,
@@ -36,6 +37,9 @@ DEFAULT_CONFIG: Dict[str, Any] = {
36
37
  "check_updates_on_start": True,
37
38
  "theme": "default",
38
39
  "setup_complete": False,
40
+ "imap_user": "",
41
+ "imap_host": "imap.gmail.com",
42
+ "imap_port": 993,
39
43
  }
40
44
 
41
45