Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
A
aisbf
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexlab
aisbf
Commits
2b07302d
Commit
2b07302d
authored
Apr 20, 2026
by
Your Name
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Providers for users ok
parent
d39326be
Changes
11
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
306 additions
and
114 deletions
+306
-114
claude.py
aisbf/auth/claude.py
+30
-7
codex.py
aisbf/auth/codex.py
+25
-5
kilo.py
aisbf/auth/kilo.py
+24
-5
qwen.py
aisbf/auth/qwen.py
+26
-6
claude.py
aisbf/providers/claude.py
+23
-12
codex.py
aisbf/providers/codex.py
+26
-8
kilo.py
aisbf/providers/kilo.py
+29
-13
qwen.py
aisbf/providers/qwen.py
+52
-13
main.py
main.py
+70
-43
aisbf-oauth2-extension.zip
static/aisbf-oauth2-extension.zip
+0
-0
user_providers.html
templates/dashboard/user_providers.html
+1
-2
No files found.
aisbf/auth/claude.py
View file @
2b07302d
...
...
@@ -101,12 +101,14 @@ class ClaudeAuth:
REDIRECT_URI
=
DEFAULT_REDIRECT_URI
CLI_USER_AGENT
=
CLI_USER_AGENT
def
__init__
(
self
,
credentials_file
:
Optional
[
str
]
=
None
,
redirect_uri
:
Optional
[
str
]
=
None
):
def
__init__
(
self
,
credentials_file
:
Optional
[
str
]
=
None
,
redirect_uri
:
Optional
[
str
]
=
None
,
skip_initial_load
:
bool
=
False
,
save_callback
:
Optional
[
callable
]
=
None
):
"""
Initialize Claude authentication.
Args:
credentials_file: Path to credentials file (default: ~/.aisbf/claude_credentials.json)
skip_initial_load: If True, do not load credentials from file on initialization
save_callback: Optional callback to save credentials instead of writing to file
"""
if
credentials_file
:
self
.
credentials_file
=
Path
(
credentials_file
)
.
expanduser
()
...
...
@@ -117,6 +119,9 @@ class ClaudeAuth:
# Allow overriding redirect URI for reverse proxy deployments
self
.
redirect_uri
=
redirect_uri
if
redirect_uri
is
not
None
else
DEFAULT_REDIRECT_URI
self
.
tokens
=
None
self
.
_save_callback
=
save_callback
if
not
skip_initial_load
:
self
.
tokens
=
self
.
_load_credentials
()
self
.
_oauth_state
=
None
# Store state for OAuth flow
self
.
_code_verifier
=
None
# Store verifier for OAuth flow
...
...
@@ -142,7 +147,25 @@ class ClaudeAuth:
return
None
def
_save_credentials
(
self
,
data
:
Dict
):
"""Save credentials to file with file locking to prevent race conditions."""
"""
Save credentials:
- If save_callback is provided, use it (database save for user providers)
- Otherwise, save to file with file locking to prevent race conditions
"""
self
.
tokens
=
data
if
self
.
_save_callback
:
# User provider: ONLY use callback, NO file fallback EVER
try
:
self
.
_save_callback
({
'tokens'
:
data
})
logger
.
info
(
"ClaudeAuth: Saved credentials via callback"
)
return
except
Exception
as
e
:
logger
.
error
(
f
"ClaudeAuth: Failed to save credentials to database: {e}"
)
# DO NOT FALLBACK TO FILE SAVE FOR REGULAR USERS
raise
# Admin/global provider ONLY: save to file
try
:
self
.
tokens
=
data
# Store id_token if received (contains account info)
...
...
aisbf/auth/codex.py
View file @
2b07302d
...
...
@@ -54,13 +54,15 @@ class CodexOAuth2:
Supports authentication with OpenAI's Codex OAuth2 endpoints.
"""
def
__init__
(
self
,
credentials_file
:
Optional
[
str
]
=
None
,
issuer
:
Optional
[
str
]
=
None
):
def
__init__
(
self
,
credentials_file
:
Optional
[
str
]
=
None
,
issuer
:
Optional
[
str
]
=
None
,
skip_initial_load
:
bool
=
False
,
save_callback
:
Optional
[
callable
]
=
None
):
"""
Initialize Codex OAuth2 client.
Args:
credentials_file: Path to credentials JSON file (default: ~/.aisbf/codex_credentials.json)
issuer: OAuth2 issuer URL (default: https://auth.openai.com)
skip_initial_load: If True, do not load credentials from file on initialization
save_callback: Optional callback to save credentials instead of writing to file
"""
# Expand and resolve path immediately to absolute path
default_path
=
os
.
path
.
expanduser
(
"~/.aisbf/codex_credentials.json"
)
...
...
@@ -74,6 +76,8 @@ class CodexOAuth2:
self
.
issuer
=
(
issuer
or
DEFAULT_ISSUER
)
.
rstrip
(
"/"
)
self
.
credentials
=
None
self
.
_save_callback
=
save_callback
if
not
skip_initial_load
:
self
.
_load_credentials
()
def
_load_credentials
(
self
)
->
None
:
...
...
@@ -89,11 +93,27 @@ class CodexOAuth2:
def
_save_credentials
(
self
,
credentials
:
Dict
[
str
,
Any
])
->
None
:
"""
Save credentials to file with secure permissions.
Save credentials:
- If save_callback is provided, use it (database save for user providers)
- Otherwise, save to file with secure permissions (admin/global providers)
Args:
credentials: Credentials dict to save
"""
self
.
credentials
=
credentials
if
self
.
_save_callback
:
# User provider: ONLY use callback, NO file fallback EVER
try
:
self
.
_save_callback
(
credentials
)
logger
.
info
(
f
"CodexOAuth2: Saved credentials via callback"
)
return
except
Exception
as
e
:
logger
.
error
(
f
"CodexOAuth2: Failed to save credentials to database: {e}"
)
# DO NOT FALLBACK TO FILE SAVE FOR REGULAR USERS
raise
# Admin/global provider ONLY: save to file
try
:
# Path is already expanded and absolute from __init__
resolved_path
=
self
.
credentials_file
...
...
aisbf/auth/kilo.py
View file @
2b07302d
...
...
@@ -40,17 +40,20 @@ class KiloOAuth2:
Supports authentication with Kilo Gateway at https://api.kilo.ai.
"""
def
__init__
(
self
,
credentials_file
:
Optional
[
str
]
=
None
,
api_base
:
Optional
[
str
]
=
None
):
def
__init__
(
self
,
credentials_file
:
Optional
[
str
]
=
None
,
api_base
:
Optional
[
str
]
=
None
,
skip_initial_load
:
bool
=
False
,
save_callback
:
Optional
[
callable
]
=
None
):
"""
Initialize Kilo OAuth2 client.
Args:
credentials_file: Path to credentials JSON file (default: ~/.kilo_credentials.json)
api_base: Base URL for Kilo API (default: https://api.kilo.ai)
skip_initial_load: If True, do not load credentials from file on initialization
"""
self
.
credentials_file
=
os
.
path
.
expanduser
(
credentials_file
)
if
credentials_file
else
os
.
path
.
expanduser
(
"~/.kilo_credentials.json"
)
self
.
api_base
=
api_base
or
os
.
environ
.
get
(
"KILO_API_URL"
,
"https://api.kilo.ai"
)
self
.
credentials
=
None
self
.
_save_callback
=
save_callback
if
not
skip_initial_load
:
self
.
_load_credentials
()
def
_load_credentials
(
self
)
->
None
:
...
...
@@ -66,11 +69,27 @@ class KiloOAuth2:
def
_save_credentials
(
self
,
credentials
:
Dict
[
str
,
Any
])
->
None
:
"""
Save credentials to file with secure permissions.
Save credentials:
- If save_callback is provided, use it (database save for user providers)
- Otherwise, save to file with secure permissions (admin/global providers)
Args:
credentials: Credentials dict to save
"""
self
.
credentials
=
credentials
if
self
.
_save_callback
:
# User provider: ONLY use callback, NO file fallback EVER
try
:
self
.
_save_callback
(
credentials
)
logger
.
info
(
f
"KiloOAuth2: Saved credentials via callback"
)
return
except
Exception
as
e
:
logger
.
error
(
f
"KiloOAuth2: Failed to save credentials to database: {e}"
)
# DO NOT FALLBACK TO FILE SAVE FOR REGULAR USERS
raise
# Admin/global provider ONLY: save to file
try
:
# Ensure directory exists
cred_dir
=
os
.
path
.
dirname
(
self
.
credentials_file
)
...
...
aisbf/auth/qwen.py
View file @
2b07302d
...
...
@@ -96,7 +96,7 @@ class QwenOAuth2:
Supports authentication with Qwen's OAuth2 endpoints and automatic token refresh.
"""
def
__init__
(
self
,
credentials_file
:
Optional
[
str
]
=
None
):
def
__init__
(
self
,
credentials_file
:
Optional
[
str
]
=
None
,
skip_initial_load
:
bool
=
False
,
save_callback
:
Optional
[
callable
]
=
None
):
"""
Initialize Qwen OAuth2 client.
...
...
@@ -105,6 +105,8 @@ class QwenOAuth2:
Args:
credentials_file: Path to credentials JSON file (default: ~/.aisbf/qwen_credentials.json)
skip_initial_load: If True, do not load credentials from file on initialization
save_callback: Optional callback to save credentials instead of writing to file
"""
logger
.
warning
(
"⚠️ Qwen OAuth2 service has been discontinued by Qwen. "
...
...
@@ -116,6 +118,8 @@ class QwenOAuth2:
self
.
credentials
=
None
self
.
_file_mod_time
=
0
self
.
_last_check
=
0
self
.
_save_callback
=
save_callback
if
not
skip_initial_load
:
self
.
_load_credentials
()
def
_load_credentials
(
self
)
->
None
:
...
...
@@ -136,11 +140,27 @@ class QwenOAuth2:
def
_save_credentials
(
self
,
credentials
:
Dict
[
str
,
Any
])
->
None
:
"""
Save credentials to file with secure permissions and file locking.
Save credentials:
- If save_callback is provided, use it (database save for user providers)
- Otherwise, save to file with secure permissions and file locking (admin/global providers)
Args:
credentials: Credentials dict to save
"""
self
.
credentials
=
credentials
if
self
.
_save_callback
:
# User provider: ONLY use callback, NO file fallback EVER
try
:
self
.
_save_callback
(
credentials
)
logger
.
info
(
f
"QwenOAuth2: Saved credentials via callback"
)
return
except
Exception
as
e
:
logger
.
error
(
f
"QwenOAuth2: Failed to save credentials to database: {e}"
)
# DO NOT FALLBACK TO FILE SAVE FOR REGULAR USERS
raise
# Admin/global provider ONLY: save to file
try
:
# Ensure directory exists
os
.
makedirs
(
os
.
path
.
dirname
(
self
.
credentials_file
),
exist_ok
=
True
)
...
...
aisbf/providers/claude.py
View file @
2b07302d
...
...
@@ -102,12 +102,21 @@ class ClaudeProviderHandler(BaseProviderHandler):
def
_load_auth_from_db
(
self
,
provider_id
:
str
,
credentials_file
:
str
):
"""
Load OAuth2 credentials from database for non-admin users.
Falls back to file-based credentials if not found in database.
Load OAuth2 credentials:
- Admin users (user_id=None): ONLY load from file
- Regular users: ONLY load from database, NO file fallback
"""
from
..auth.claude
import
ClaudeAuth
import
logging
if
self
.
user_id
is
None
:
# Admin user: ONLY use file-based credentials
logging
.
getLogger
(
__name__
)
.
info
(
f
"ClaudeProviderHandler: Admin user, loading credentials from file: {credentials_file}"
)
return
ClaudeAuth
(
credentials_file
=
credentials_file
)
# Regular user: ONLY use database credentials, NO file fallback
try
:
from
..database
import
get_database
from
..auth.claude
import
ClaudeAuth
db
=
get_database
()
if
db
:
db_creds
=
db
.
get_user_oauth2_credentials
(
...
...
@@ -116,22 +125,24 @@ class ClaudeProviderHandler(BaseProviderHandler):
auth_type
=
'claude_oauth2'
)
if
db_creds
and
db_creds
.
get
(
'credentials'
):
# Create auth instance with database credentials
auth
=
ClaudeAuth
(
credentials_file
=
credentials_file
)
# Override the loaded credentials with database credentials
# Create auth instance with skip_initial_load=True to avoid file read
# Pass save callback to save credentials back to database
auth
=
ClaudeAuth
(
credentials_file
=
credentials_file
,
skip_initial_load
=
True
,
save_callback
=
lambda
creds
:
self
.
_save_auth_to_db
(
creds
)
)
# Set tokens directly from database
auth
.
tokens
=
db_creds
[
'credentials'
]
.
get
(
'tokens'
,
{})
import
logging
logging
.
getLogger
(
__name__
)
.
info
(
f
"ClaudeProviderHandler: Loaded credentials from database for user {self.user_id}"
)
return
auth
except
Exception
as
e
:
import
logging
logging
.
getLogger
(
__name__
)
.
warning
(
f
"ClaudeProviderHandler: Failed to load credentials from database: {e}"
)
# Fall back to file-based credentials
from
..auth.claude
import
ClaudeAuth
import
logging
logging
.
getLogger
(
__name__
)
.
info
(
f
"ClaudeProviderHandler: Falling back to file-based credentials for user {self.user_id}"
)
return
ClaudeAuth
(
credentials_file
=
credentials_file
)
# For regular users, NO file fallback - return empty auth instance
logging
.
getLogger
(
__name__
)
.
info
(
f
"ClaudeProviderHandler: No database credentials found for user {self.user_id}, returning unauthenticated instance"
)
return
ClaudeAuth
(
credentials_file
=
credentials_file
,
skip_initial_load
=
True
)
def
_init_session_identifiers
(
self
):
"""Initialize persistent session identifiers (device_id, account_uuid, session_id)."""
...
...
aisbf/providers/codex.py
View file @
2b07302d
...
...
@@ -112,9 +112,22 @@ class CodexProviderHandler(BaseProviderHandler):
def
_load_oauth2_from_db
(
self
,
provider_id
:
str
,
credentials_file
:
str
,
issuer
:
str
)
->
CodexOAuth2
:
"""
Load OAuth2 credentials from database for non-admin users.
Falls back to file-based credentials if not found in database.
Load OAuth2 credentials:
- Admin users (user_id=None): ONLY load from file
- Regular users: ONLY load from database, NO file fallback
"""
from
..auth.codex
import
CodexOAuth2
import
logging
if
self
.
user_id
is
None
:
# Admin user: ONLY use file-based credentials
logging
.
getLogger
(
__name__
)
.
info
(
f
"CodexProviderHandler: Admin user, loading credentials from file: {credentials_file}"
)
return
CodexOAuth2
(
credentials_file
=
credentials_file
,
issuer
=
issuer
,
)
# Regular user: ONLY use database credentials, NO file fallback
try
:
from
..database
import
get_database
db
=
get_database
()
...
...
@@ -125,23 +138,28 @@ class CodexProviderHandler(BaseProviderHandler):
auth_type
=
'codex_oauth2'
)
if
db_creds
and
db_creds
.
get
(
'credentials'
):
# Create OAuth2 instance with database credentials
# Create OAuth2 instance with skip_initial_load=True to avoid file read
# Pass save callback to save credentials back to database
oauth2
=
CodexOAuth2
(
credentials_file
=
credentials_file
,
issuer
=
issuer
,
skip_initial_load
=
True
,
save_callback
=
lambda
creds
:
self
.
_save_oauth2_to_db
(
creds
)
)
#
Override the loaded credentials with database credentials
#
Set credentials directly from database
oauth2
.
credentials
=
db_creds
[
'credentials'
]
logg
er
.
info
(
f
"CodexProviderHandler: Loaded credentials from database for user {self.user_id}"
)
logg
ing
.
getLogger
(
__name__
)
.
info
(
f
"CodexProviderHandler: Loaded credentials from database for user {self.user_id}"
)
return
oauth2
except
Exception
as
e
:
logg
er
.
warning
(
f
"CodexProviderHandler: Failed to load credentials from database: {e}"
)
logg
ing
.
getLogger
(
__name__
)
.
warning
(
f
"CodexProviderHandler: Failed to load credentials from database: {e}"
)
# F
all back to file-based credentials
logg
er
.
info
(
f
"CodexProviderHandler: Falling back to file-based credentials for user {self.user_id}
"
)
# F
or regular users, NO file fallback - return empty auth instance
logg
ing
.
getLogger
(
__name__
)
.
info
(
f
"CodexProviderHandler: No database credentials found for user {self.user_id}, returning unauthenticated instance
"
)
return
CodexOAuth2
(
credentials_file
=
credentials_file
,
issuer
=
issuer
,
skip_initial_load
=
True
,
save_callback
=
lambda
creds
:
self
.
_save_oauth2_to_db
(
creds
)
)
async
def
_get_valid_api_key
(
self
)
->
str
:
...
...
aisbf/providers/kilo.py
View file @
2b07302d
...
...
@@ -110,12 +110,21 @@ class KiloProviderHandler(BaseProviderHandler):
def
_load_oauth2_from_db
(
self
,
provider_id
:
str
,
credentials_file
:
str
,
api_base
:
str
):
"""
Load OAuth2 credentials from database for non-admin users.
Falls back to file-based credentials if not found in database.
Load OAuth2 credentials:
- Admin users (user_id=None): ONLY load from file
- Regular users: ONLY load from database, NO file fallback
"""
from
..auth.kilo
import
KiloOAuth2
import
logging
if
self
.
user_id
is
None
:
# Admin user: ONLY use file-based credentials
logging
.
getLogger
(
__name__
)
.
info
(
f
"KiloProviderHandler: Admin user, loading credentials from file: {credentials_file}"
)
return
KiloOAuth2
(
credentials_file
=
credentials_file
,
api_base
=
api_base
)
# Regular user: ONLY use database credentials, NO file fallback
try
:
from
..database
import
get_database
from
..auth.kilo
import
KiloOAuth2
db
=
get_database
()
if
db
:
db_creds
=
db
.
get_user_oauth2_credentials
(
...
...
@@ -124,22 +133,29 @@ class KiloProviderHandler(BaseProviderHandler):
auth_type
=
'kilo_oauth2'
)
if
db_creds
and
db_creds
.
get
(
'credentials'
):
# Create OAuth2 instance with database credentials
oauth2
=
KiloOAuth2
(
credentials_file
=
credentials_file
,
api_base
=
api_base
)
# Override the loaded credentials with database credentials
# Create OAuth2 instance with skip_initial_load=True to avoid file read
# Pass save callback to save credentials back to database
oauth2
=
KiloOAuth2
(
credentials_file
=
credentials_file
,
api_base
=
api_base
,
skip_initial_load
=
True
,
save_callback
=
lambda
creds
:
self
.
_save_oauth2_to_db
(
creds
)
)
# Set credentials directly from database
oauth2
.
credentials
=
db_creds
[
'credentials'
]
import
logging
logging
.
getLogger
(
__name__
)
.
info
(
f
"KiloProviderHandler: Loaded credentials from database for user {self.user_id}"
)
return
oauth2
except
Exception
as
e
:
import
logging
logging
.
getLogger
(
__name__
)
.
warning
(
f
"KiloProviderHandler: Failed to load credentials from database: {e}"
)
# Fall back to file-based credentials
from
..auth.kilo
import
KiloOAuth2
import
logging
logging
.
getLogger
(
__name__
)
.
info
(
f
"KiloProviderHandler: Falling back to file-based credentials for user {self.user_id}"
)
return
KiloOAuth2
(
credentials_file
=
credentials_file
,
api_base
=
api_base
)
# For regular users, NO file fallback - return empty auth instance
logging
.
getLogger
(
__name__
)
.
info
(
f
"KiloProviderHandler: No database credentials found for user {self.user_id}, returning unauthenticated instance"
)
return
KiloOAuth2
(
credentials_file
=
credentials_file
,
api_base
=
api_base
,
skip_initial_load
=
True
,
save_callback
=
lambda
creds
:
self
.
_save_oauth2_to_db
(
creds
)
)
def
_save_oauth2_to_db
(
self
,
credentials
:
Dict
)
->
None
:
"""
...
...
aisbf/providers/qwen.py
View file @
2b07302d
...
...
@@ -98,12 +98,21 @@ class QwenProviderHandler(BaseProviderHandler):
def
_load_auth_from_db
(
self
,
provider_id
:
str
,
credentials_file
:
str
):
"""
Load OAuth2 credentials from database for non-admin users.
Falls back to file-based credentials if not found in database.
Load OAuth2 credentials:
- Admin users (user_id=None): ONLY load from file
- Regular users: ONLY load from database, NO file fallback
"""
from
..auth.qwen
import
QwenOAuth2
import
logging
if
self
.
user_id
is
None
:
# Admin user: ONLY use file-based credentials
logging
.
getLogger
(
__name__
)
.
info
(
f
"QwenProviderHandler: Admin user, loading credentials from file: {credentials_file}"
)
return
QwenOAuth2
(
credentials_file
=
credentials_file
)
# Regular user: ONLY use database credentials, NO file fallback
try
:
from
..database
import
get_database
from
..auth.qwen
import
QwenOAuth2
db
=
get_database
()
if
db
:
db_creds
=
db
.
get_user_oauth2_credentials
(
...
...
@@ -112,22 +121,52 @@ class QwenProviderHandler(BaseProviderHandler):
auth_type
=
'qwen_oauth2'
)
if
db_creds
and
db_creds
.
get
(
'credentials'
):
# Create auth instance with database credentials
auth
=
QwenOAuth2
(
credentials_file
=
credentials_file
)
# Override the loaded credentials with database credentials
# Create auth instance with skip_initial_load=True to avoid file read
# Pass save callback to save credentials back to database
auth
=
QwenOAuth2
(
credentials_file
=
credentials_file
,
skip_initial_load
=
True
,
save_callback
=
lambda
creds
:
self
.
_save_auth_to_db
(
creds
)
)
# Set credentials directly from database
auth
.
credentials
=
db_creds
[
'credentials'
]
import
logging
logging
.
getLogger
(
__name__
)
.
info
(
f
"QwenProviderHandler: Loaded credentials from database for user {self.user_id}"
)
return
auth
except
Exception
as
e
:
import
logging
logging
.
getLogger
(
__name__
)
.
warning
(
f
"QwenProviderHandler: Failed to load credentials from database: {e}"
)
# Fall back to file-based credentials
from
..auth.qwen
import
QwenOAuth2
# For regular users, NO file fallback - return empty auth instance
logging
.
getLogger
(
__name__
)
.
info
(
f
"QwenProviderHandler: No database credentials found for user {self.user_id}, returning unauthenticated instance"
)
return
QwenOAuth2
(
credentials_file
=
credentials_file
,
skip_initial_load
=
True
,
save_callback
=
lambda
creds
:
self
.
_save_auth_to_db
(
creds
)
)
def
_save_auth_to_db
(
self
,
credentials
:
Dict
)
->
None
:
"""
Save OAuth2 credentials to database for non-admin users.
This is called after successful device flow authentication.
"""
if
self
.
user_id
is
None
:
# Admin user uses file-based credentials, nothing to save to DB
return
try
:
from
..database
import
get_database
db
=
get_database
()
if
db
:
db
.
save_user_oauth2_credentials
(
user_id
=
self
.
user_id
,
provider_id
=
self
.
provider_id
,
auth_type
=
'qwen_oauth2'
,
credentials
=
credentials
)
import
logging
logging
.
getLogger
(
__name__
)
.
info
(
f
"QwenProviderHandler: Falling back to file-based credentials for user {self.user_id}"
)
return
QwenOAuth2
(
credentials_file
=
credentials_file
)
logging
.
getLogger
(
__name__
)
.
info
(
f
"QwenProviderHandler: Saved credentials to database for user {self.user_id}"
)
except
Exception
as
e
:
import
logging
logging
.
getLogger
(
__name__
)
.
warning
(
f
"QwenProviderHandler: Failed to save credentials to database: {e}"
)
async
def
_get_sdk_client
(
self
):
"""Get or create an OpenAI SDK client configured with authentication (OAuth2 or API key)."""
...
...
main.py
View file @
2b07302d
This diff is collapsed.
Click to expand it.
static/aisbf-oauth2-extension.zip
View file @
2b07302d
No preview for this file type
templates/dashboard/user_providers.html
View file @
2b07302d
...
...
@@ -134,6 +134,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
{% block extra_js %}
<script>
let
providersData
=
{};
let
expandedProviders
=
new
Set
();
let
rawProviders
=
{{
user_providers_json
|
safe
}};
// Convert user providers format to the format expected by the UI
...
...
@@ -141,8 +142,6 @@ rawProviders.forEach(provider => {
providersData
[
provider
.
provider_id
]
=
provider
.
config
;
});
let
expandedProviders
=
new
Set
();
// Chunk size: 512KB chunks for maximum compatibility with restrictive proxies
const
CHUNK_SIZE
=
512
*
1024
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment