1
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
# Auth API Reference
2
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
3
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
::: video_processor.auth
4
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
5
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
---
6
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
7
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
## Overview
8
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
9
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
The `video_processor.auth` module provides a unified OAuth and authentication strategy for all PlanOpticon source connectors. It supports multiple authentication methods tried in a consistent order:
10
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
11
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
1. **Saved token** -- load from disk, auto-refresh if expired
12
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
2. **Client Credentials** -- server-to-server OAuth (e.g., Zoom S2S)
13
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
3. **OAuth 2.0 PKCE** -- interactive Authorization Code flow with PKCE
14
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
4. **API key fallback** -- environment variable lookup
15
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
16
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Tokens are persisted to `~/.planopticon/` and automatically refreshed on expiry.
17
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
18
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
---
19
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
20
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
## AuthConfig
21
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
22
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```python
23
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
from video_processor.auth import AuthConfig
24
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
25
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
26
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Dataclass configuring authentication for a specific service. Defines OAuth endpoints, client credentials, API key fallback, scopes, and token storage.
27
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
28
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
### Fields
29
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
30
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| Field | Type | Default | Description |
31
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
|---|---|---|---|
32
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `service` | `str` | *required* | Service identifier (e.g., `"zoom"`, `"notion"`) |
33
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `oauth_authorize_url` | `Optional[str]` | `None` | OAuth authorization endpoint URL |
34
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `oauth_token_url` | `Optional[str]` | `None` | OAuth token exchange endpoint URL |
35
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `client_id` | `Optional[str]` | `None` | OAuth client ID (direct value) |
36
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `client_secret` | `Optional[str]` | `None` | OAuth client secret (direct value) |
37
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `client_id_env` | `Optional[str]` | `None` | Environment variable for client ID |
38
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `client_secret_env` | `Optional[str]` | `None` | Environment variable for client secret |
39
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `api_key_env` | `Optional[str]` | `None` | Environment variable for API key fallback |
40
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `scopes` | `List[str]` | `[]` | OAuth scopes to request |
41
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `redirect_uri` | `str` | `"urn:ietf:wg:oauth:2.0:oob"` | Redirect URI for auth code flow |
42
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `account_id` | `Optional[str]` | `None` | Account ID for client credentials grant (direct value) |
43
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `account_id_env` | `Optional[str]` | `None` | Environment variable for account ID |
44
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `token_path` | `Optional[Path]` | `None` | Custom token storage path |
45
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
46
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
### Resolved Properties
47
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
48
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
These properties resolve values by checking the direct field first, then falling back to the environment variable.
49
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
50
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| Property | Return Type | Description |
51
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
|---|---|---|
52
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `resolved_client_id` | `Optional[str]` | Client ID from `client_id` or `os.environ[client_id_env]` |
53
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `resolved_client_secret` | `Optional[str]` | Client secret from `client_secret` or `os.environ[client_secret_env]` |
54
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `resolved_api_key` | `Optional[str]` | API key from `os.environ[api_key_env]` |
55
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `resolved_account_id` | `Optional[str]` | Account ID from `account_id` or `os.environ[account_id_env]` |
56
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `resolved_token_path` | `Path` | Token file path: `token_path` or `~/.planopticon/{service}_token.json` |
57
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `supports_oauth` | `bool` | `True` if both `oauth_authorize_url` and `oauth_token_url` are set |
58
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
59
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```python
60
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
from video_processor.auth import AuthConfig
61
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
62
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
config = AuthConfig(
63
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
service="notion",
64
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
oauth_authorize_url="https://api.notion.com/v1/oauth/authorize",
65
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
oauth_token_url="https://api.notion.com/v1/oauth/token",
66
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
client_id_env="NOTION_CLIENT_ID",
67
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
client_secret_env="NOTION_CLIENT_SECRET",
68
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
api_key_env="NOTION_API_KEY",
69
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
scopes=["read_content"],
70
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
)
71
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
72
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
# Check resolved values
73
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
print(config.resolved_client_id) # From NOTION_CLIENT_ID env var
74
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
print(config.supports_oauth) # True
75
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
print(config.resolved_token_path) # ~/.planopticon/notion_token.json
76
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
77
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
78
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
---
79
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
80
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
## AuthResult
81
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
82
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```python
83
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
from video_processor.auth import AuthResult
84
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
85
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
86
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Dataclass representing the result of an authentication attempt.
87
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
88
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| Field | Type | Default | Description |
89
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
|---|---|---|---|
90
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `success` | `bool` | *required* | Whether authentication succeeded |
91
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `access_token` | `Optional[str]` | `None` | The access token (if successful) |
92
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `method` | `Optional[str]` | `None` | Auth method used: `"saved_token"`, `"oauth_pkce"`, `"client_credentials"`, `"api_key"` |
93
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `expires_at` | `Optional[float]` | `None` | Token expiration as Unix timestamp |
94
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `refresh_token` | `Optional[str]` | `None` | OAuth refresh token (if available) |
95
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `error` | `Optional[str]` | `None` | Error message (if failed) |
96
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
97
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```python
98
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
result = manager.authenticate()
99
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
if result.success:
100
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
print(f"Authenticated via {result.method}")
101
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
print(f"Token: {result.access_token[:20]}...")
102
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
if result.expires_at:
103
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
import time
104
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
remaining = result.expires_at - time.time()
105
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
print(f"Expires in {remaining/60:.0f} minutes")
106
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
else:
107
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
print(f"Auth failed: {result.error}")
108
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
109
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
110
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
---
111
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
112
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
## OAuthManager
113
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
114
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```python
115
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
from video_processor.auth import OAuthManager
116
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
117
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
118
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Manages the full authentication lifecycle for a service. Tries auth methods in priority order and handles token persistence, refresh, and PKCE flow.
119
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
120
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
### Constructor
121
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
122
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```python
123
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
def __init__(self, config: AuthConfig)
124
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
125
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
126
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| Parameter | Type | Description |
127
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
|---|---|---|
128
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `config` | `AuthConfig` | Authentication configuration for the target service |
129
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
130
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
### authenticate()
131
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
132
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```python
133
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
def authenticate(self) -> AuthResult
134
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
135
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
136
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Run the full auth chain and return the result. Methods are tried in order:
137
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
138
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
1. **Saved token** -- checks `~/.planopticon/{service}_token.json`, refreshes if expired
139
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
2. **Client Credentials** -- if `account_id` is set and OAuth is configured, uses the client credentials grant (server-to-server)
140
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
3. **OAuth PKCE** -- if OAuth is configured and client ID is available, opens a browser for interactive authorization with PKCE
141
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
4. **API key** -- falls back to the environment variable specified in `api_key_env`
142
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
143
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
**Returns:** `AuthResult` -- success/failure with token and method details.
144
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
145
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
If all methods fail, returns an `AuthResult` with `success=False` and a helpful error message listing which environment variables to set.
146
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
147
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
### get_token()
148
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
149
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```python
150
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
def get_token(self) -> Optional[str]
151
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
152
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
153
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Convenience method: run `authenticate()` and return just the access token string.
154
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
155
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
**Returns:** `Optional[str]` -- the access token, or `None` if authentication failed.
156
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
157
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
### clear_token()
158
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
159
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```python
160
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
def clear_token(self) -> None
161
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
162
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
163
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Remove the saved token file for this service (effectively a logout). The next `authenticate()` call will require re-authentication.
164
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
165
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
---
166
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
167
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
## Authentication Flows
168
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
169
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
### Saved Token (auto-refresh)
170
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
171
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Tokens are saved to `~/.planopticon/{service}_token.json` as JSON. On each `authenticate()` call, the saved token is loaded and checked:
172
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
173
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- If the token has not expired (`time.time() < expires_at`), it is returned immediately
174
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- If expired but a refresh token is available, the manager attempts to refresh using the OAuth token endpoint
175
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
- The refreshed token is saved back to disk
176
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
177
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
### Client Credentials Grant
178
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
179
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Used for server-to-server authentication (e.g., Zoom Server-to-Server OAuth). Requires `account_id`, `client_id`, and `client_secret`. Sends a POST to the token endpoint with `grant_type=account_credentials`.
180
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
181
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
### OAuth 2.0 Authorization Code with PKCE
182
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
183
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Interactive flow for user authentication:
184
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
185
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
1. Generates a PKCE code verifier and S256 challenge
186
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
2. Constructs the authorization URL with client ID, redirect URI, scopes, and PKCE challenge
187
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
3. Opens the URL in the user's browser
188
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
4. Prompts the user to paste the authorization code
189
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
5. Exchanges the code for tokens at the token endpoint
190
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
6. Saves the tokens to disk
191
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
192
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
### API Key Fallback
193
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
194
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
If no OAuth flow succeeds, falls back to checking the environment variable specified in `api_key_env`. Returns the value directly as the access token.
195
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
196
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
---
197
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
198
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
## KNOWN_CONFIGS
199
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
200
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```python
201
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
from video_processor.auth import KNOWN_CONFIGS
202
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
203
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
204
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Pre-built `AuthConfig` instances for supported services. These cover the most common cloud integrations and can be used directly or as templates for custom configurations.
205
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
206
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| Service Key | Service | OAuth Endpoints | Client ID Env | API Key Env |
207
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
|---|---|---|---|---|
208
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `"zoom"` | Zoom | `zoom.us/oauth/...` | `ZOOM_CLIENT_ID` | -- |
209
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `"notion"` | Notion | `api.notion.com/v1/oauth/...` | `NOTION_CLIENT_ID` | `NOTION_API_KEY` |
210
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `"dropbox"` | Dropbox | `dropbox.com/oauth2/...` | `DROPBOX_APP_KEY` | `DROPBOX_ACCESS_TOKEN` |
211
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `"github"` | GitHub | `github.com/login/oauth/...` | `GITHUB_CLIENT_ID` | `GITHUB_TOKEN` |
212
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `"google"` | Google | `accounts.google.com/o/oauth2/...` | `GOOGLE_CLIENT_ID` | `GOOGLE_API_KEY` |
213
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `"microsoft"` | Microsoft | `login.microsoftonline.com/.../oauth2/...` | `MICROSOFT_CLIENT_ID` | -- |
214
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
215
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
### Zoom
216
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
217
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Supports both Server-to-Server (via `ZOOM_ACCOUNT_ID`) and OAuth PKCE flows.
218
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
219
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```bash
220
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
# Server-to-Server
221
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
export ZOOM_CLIENT_ID="..."
222
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
export ZOOM_CLIENT_SECRET="..."
223
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
export ZOOM_ACCOUNT_ID="..."
224
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
225
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
# Or interactive OAuth (omit ZOOM_ACCOUNT_ID)
226
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
export ZOOM_CLIENT_ID="..."
227
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
export ZOOM_CLIENT_SECRET="..."
228
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
229
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
230
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
### Google (Drive, Meet, Workspace)
231
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
232
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Supports OAuth PKCE and API key fallback. Scopes include Drive and Docs read-only access.
233
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
234
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```bash
235
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
export GOOGLE_CLIENT_ID="..."
236
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
export GOOGLE_CLIENT_SECRET="..."
237
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
# Or for API-key-only access:
238
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
export GOOGLE_API_KEY="..."
239
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
240
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
241
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
### GitHub
242
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
243
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Supports OAuth PKCE and personal access token. Requests `repo` and `read:org` scopes.
244
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
245
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```bash
246
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
# OAuth
247
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
export GITHUB_CLIENT_ID="..."
248
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
export GITHUB_CLIENT_SECRET="..."
249
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
# Or personal access token
250
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
export GITHUB_TOKEN="ghp_..."
251
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
252
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
253
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
---
254
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
255
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
## Helper Functions
256
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
257
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
### get_auth_config()
258
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
259
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```python
260
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
def get_auth_config(service: str) -> Optional[AuthConfig]
261
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
262
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
263
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Get a pre-built `AuthConfig` for a known service.
264
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
265
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
**Parameters:**
266
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
267
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| Parameter | Type | Description |
268
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
|---|---|---|
269
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
| `service` | `str` | Service name (e.g., `"zoom"`, `"notion"`, `"github"`) |
270
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
271
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
**Returns:** `Optional[AuthConfig]` -- the config, or `None` if the service is not in `KNOWN_CONFIGS`.
272
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
273
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
### get_auth_manager()
274
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
275
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```python
276
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
def get_auth_manager(service: str) -> Optional[OAuthManager]
277
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
278
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
279
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Get an `OAuthManager` for a known service. Convenience wrapper that looks up the config and creates the manager in one call.
280
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
281
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
**Returns:** `Optional[OAuthManager]` -- the manager, or `None` if the service is not known.
282
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
283
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
---
284
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
285
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
## Usage Examples
286
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
287
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
### Quick authentication for a known service
288
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
289
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```python
290
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
from video_processor.auth import get_auth_manager
291
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
292
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
manager = get_auth_manager("zoom")
293
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
if manager:
294
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
result = manager.authenticate()
295
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
if result.success:
296
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
print(f"Authenticated via {result.method}")
297
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
# Use result.access_token for API calls
298
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
else:
299
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
print(f"Failed: {result.error}")
300
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
301
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
302
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
### Custom service configuration
303
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
304
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```python
305
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
from video_processor.auth import AuthConfig, OAuthManager
306
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
307
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
config = AuthConfig(
308
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
service="my_service",
309
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
oauth_authorize_url="https://my-service.com/oauth/authorize",
310
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
oauth_token_url="https://my-service.com/oauth/token",
311
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
client_id_env="MY_SERVICE_CLIENT_ID",
312
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
client_secret_env="MY_SERVICE_CLIENT_SECRET",
313
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
api_key_env="MY_SERVICE_API_KEY",
314
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
scopes=["read", "write"],
315
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
)
316
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
317
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
manager = OAuthManager(config)
318
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
token = manager.get_token() # Returns str or None
319
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
320
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
321
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
### Using auth in a custom source connector
322
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
323
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```python
324
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
from pathlib import Path
325
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
from typing import List, Optional
326
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
327
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
from video_processor.auth import OAuthManager, AuthConfig
328
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
from video_processor.sources.base import BaseSource, SourceFile
329
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
330
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
class CustomSource(BaseSource):
331
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
def __init__(self):
332
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
self._config = AuthConfig(
333
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
service="custom",
334
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
api_key_env="CUSTOM_API_KEY",
335
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
)
336
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
self._manager = OAuthManager(self._config)
337
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
self._token: Optional[str] = None
338
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
339
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
def authenticate(self) -> bool:
340
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
self._token = self._manager.get_token()
341
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
return self._token is not None
342
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
343
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
def list_videos(self, **kwargs) -> List[SourceFile]:
344
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
# Use self._token to query the API
345
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
...
346
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
347
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
def download(self, file: SourceFile, destination: Path) -> Path:
348
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
# Use self._token for authenticated downloads
349
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
...
350
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
351
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
352
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
### Logout / clear saved token
353
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
354
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```python
355
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
from video_processor.auth import get_auth_manager
356
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
357
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
manager = get_auth_manager("zoom")
358
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
if manager:
359
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
manager.clear_token()
360
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
print("Zoom token cleared")
361
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
362
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
363
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
### Token storage location
364
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
365
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
All tokens are stored under `~/.planopticon/`:
366
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
367
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
368
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
~/.planopticon/
369
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
zoom_token.json
370
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
notion_token.json
371
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
github_token.json
372
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
google_token.json
373
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
microsoft_token.json
374
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
dropbox_token.json
375
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
```
376
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
377
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!
Each file contains a JSON object with `access_token`, `refresh_token` (if applicable), `expires_at`, and client credentials for refresh.
378
{ copied = false; pop = false }, 1000)" :class="copied && 'copied'">
Copy link Copied!