bugfix: langflow application losing store api-key on refresh page/backend (#2960)
* changing api key journey * refactor(api_key.py): remove unnecessary code related to config_dir and secret_key_path refactor(login.py): refactor setting api_key cookie to use user's store_api_key refactor(variable/service.py): re-encrypt stored value if secret_key changes to ensure validity * 📝 (api_key.py): Remove unused imports and clean up code for better readability 📝 (login.py): Remove unused imports and clean up code for better readability 📝 (auth/utils.py): Remove unused imports and clean up code for better readability 📝 (store/service.py): Remove unused imports and clean up code for better readability * 🔧 (utils.py): replace hashing logic with random key generation for key length less than 32 bytes to ensure key length is always 32 bytes 📝 (utils.py): update comments for clarity and accuracy regarding key generation and encryption process --------- Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@langflow.org>
This commit is contained in:
parent
55693c920d
commit
b6774cf3d8
3 changed files with 44 additions and 2 deletions
|
|
@ -1,7 +1,7 @@
|
|||
from typing import TYPE_CHECKING
|
||||
from uuid import UUID
|
||||
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from fastapi import APIRouter, Depends, HTTPException, Response
|
||||
from sqlmodel import Session
|
||||
|
||||
from langflow.api.v1.schemas import ApiKeyCreateRequest, ApiKeysResponse
|
||||
|
|
@ -62,17 +62,32 @@ def delete_api_key_route(
|
|||
@router.post("/store")
|
||||
def save_store_api_key(
|
||||
api_key_request: ApiKeyCreateRequest,
|
||||
response: Response,
|
||||
current_user: User = Depends(auth_utils.get_current_active_user),
|
||||
db: Session = Depends(get_session),
|
||||
settings_service=Depends(get_settings_service),
|
||||
):
|
||||
auth_settings = settings_service.auth_settings
|
||||
|
||||
try:
|
||||
api_key = api_key_request.api_key
|
||||
|
||||
# Encrypt the API key
|
||||
encrypted = auth_utils.encrypt_api_key(api_key, settings_service=settings_service)
|
||||
current_user.store_api_key = encrypted
|
||||
db.add(current_user)
|
||||
db.commit()
|
||||
|
||||
response.set_cookie(
|
||||
"apikey_tkn_lflw",
|
||||
encrypted,
|
||||
httponly=auth_settings.ACCESS_HTTPONLY,
|
||||
samesite=auth_settings.ACCESS_SAME_SITE,
|
||||
secure=auth_settings.ACCESS_SECURE,
|
||||
expires=None, # Set to None to make it a session cookie
|
||||
domain=auth_settings.COOKIE_DOMAIN,
|
||||
)
|
||||
|
||||
return {"detail": "API Key saved"}
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=400, detail=str(e)) from e
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
from fastapi import APIRouter, Depends, HTTPException, Request, Response, status
|
||||
from fastapi.security import OAuth2PasswordRequestForm
|
||||
from langflow.services.database.models.user.crud import get_user_by_id
|
||||
from sqlmodel import Session
|
||||
|
||||
from langflow.api.v1.schemas import Token
|
||||
|
|
@ -57,6 +58,15 @@ async def login_to_get_access_token(
|
|||
expires=auth_settings.ACCESS_TOKEN_EXPIRE_SECONDS,
|
||||
domain=auth_settings.COOKIE_DOMAIN,
|
||||
)
|
||||
response.set_cookie(
|
||||
"apikey_tkn_lflw",
|
||||
str(user.store_api_key),
|
||||
httponly=auth_settings.ACCESS_HTTPONLY,
|
||||
samesite=auth_settings.ACCESS_SAME_SITE,
|
||||
secure=auth_settings.ACCESS_SECURE,
|
||||
expires=None, # Set to None to make it a session cookie
|
||||
domain=auth_settings.COOKIE_DOMAIN,
|
||||
)
|
||||
variable_service.initialize_user_variables(user.id, db)
|
||||
# Create default folder for user if it doesn't exist
|
||||
create_default_folder_if_it_doesnt_exist(db, user.id)
|
||||
|
|
@ -74,6 +84,7 @@ async def auto_login(
|
|||
response: Response, db: Session = Depends(get_session), settings_service=Depends(get_settings_service)
|
||||
):
|
||||
auth_settings = settings_service.auth_settings
|
||||
|
||||
if settings_service.auth_settings.AUTO_LOGIN:
|
||||
user_id, tokens = create_user_longterm_token(db)
|
||||
response.set_cookie(
|
||||
|
|
@ -86,6 +97,22 @@ async def auto_login(
|
|||
domain=auth_settings.COOKIE_DOMAIN,
|
||||
)
|
||||
|
||||
user = get_user_by_id(db, user_id)
|
||||
|
||||
if user:
|
||||
if user.store_api_key is None:
|
||||
user.store_api_key = ""
|
||||
|
||||
response.set_cookie(
|
||||
"apikey_tkn_lflw",
|
||||
str(user.store_api_key), # Ensure it's a string
|
||||
httponly=auth_settings.ACCESS_HTTPONLY,
|
||||
samesite=auth_settings.ACCESS_SAME_SITE,
|
||||
secure=auth_settings.ACCESS_SECURE,
|
||||
expires=None, # Set to None to make it a session cookie
|
||||
domain=auth_settings.COOKIE_DOMAIN,
|
||||
)
|
||||
|
||||
return tokens
|
||||
|
||||
raise HTTPException(
|
||||
|
|
@ -140,4 +167,5 @@ async def refresh_token(
|
|||
async def logout(response: Response):
|
||||
response.delete_cookie("refresh_token_lf")
|
||||
response.delete_cookie("access_token_lf")
|
||||
response.delete_cookie("apikey_tkn_lflw")
|
||||
return {"message": "Logout successful"}
|
||||
|
|
|
|||
|
|
@ -117,7 +117,6 @@ export function AuthProvider({ children }): React.ReactElement {
|
|||
}
|
||||
|
||||
function storeApiKey(apikey: string) {
|
||||
cookies.set(LANGFLOW_API_TOKEN, apikey, { path: "/" });
|
||||
setApiKey(apikey);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue