From 73148d2b097fe7dcc570cff718e5398f746579ee Mon Sep 17 00:00:00 2001 From: Niranjan Date: Tue, 7 Apr 2026 03:57:44 +0530 Subject: [PATCH] new changes --- .../core/__pycache__/__init__.cpython-314.pyc | Bin 0 -> 183 bytes .../core/__pycache__/security.cpython-314.pyc | Bin 0 -> 3118 bytes YakPanel-server/backend/scripts/seed_admin.py | 16 ++++++-- YakPanel-server/frontend/src/api/client.ts | 37 +++++++++++++++--- 4 files changed, 43 insertions(+), 10 deletions(-) create mode 100644 YakPanel-server/backend/app/core/__pycache__/__init__.cpython-314.pyc create mode 100644 YakPanel-server/backend/app/core/__pycache__/security.cpython-314.pyc diff --git a/YakPanel-server/backend/app/core/__pycache__/__init__.cpython-314.pyc b/YakPanel-server/backend/app/core/__pycache__/__init__.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..287f1216ec29be3bba5d282a996d46057973d96c GIT binary patch literal 183 zcmdPqlZtjXIxFod*!7olNDg*M95|gu2^HO3G3kqVA w^NUhr;^Q;(GE3s)^$IF)aoFVMrB7{vI*%*e=C#0+Es0P=V+wg3PC literal 0 HcmV?d00001 diff --git a/YakPanel-server/backend/app/core/__pycache__/security.cpython-314.pyc b/YakPanel-server/backend/app/core/__pycache__/security.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..739f1c4a871fbedbc580bc014cff41258f1299ef GIT binary patch literal 3118 zcma)8O>Epm6dtb~?{1vzW}Brcq-mUngsgxRwJ9kr3T*?`28j~fuz=WNIkuaaZr0X# zmUMGkAr4RuEk9Cw;J_hBAoakZ2M)a;ap0J!sRC9}L2%*LDxe@vyf^lGw-JIq$uslj z&5Y-L?{6N@baxV<+<^_}s}4ebMW#u>bK3e6x(3k*BX1E+m=THs6N(9z7(_lXBNinl z@v%75QIwfnOtK{BrI}PQ&C-0_G1FO8m@-JtDnn!WQ~F4yhh?-b7(}5hafn?N}3#TQ0bJ1S1{h-sb zJ!+fqd&?9+Rs4`-_(b@&o`t4CO60A?k@pC(U~VsYMOYLxp$w9cv_#ujEJu(LazF(2 zrQeYcGG4`Ss=87(W4kWQTFD z9(3utQLVZRP|$VS2Y>2@&mV%OLAFUkcw+D35`rdtsLA*9(IN`AylqsSK!afREA(!Z|sUoGBLM%JVe zuIcIftP+Q)274bML}MQb7{*0 z^P%Rmkr_c2Q!}G`iIVVGG;4t+_L5eDnvIc&w~{IzLVi{Y-BjDc3x#jTB8D$ad9qEj#Fhd`tma$2%ne zX6_{Ow{s6)8T@$gW^VuIXK&>WejxuAPprOi{lezto9mNrZj6*~<;w5NKSFC9ymz~u;n?n=pLlfVnHjiuT$F&XR%$jtjmBgA}jPD%8e(My! z%>U-wI5z%0vfHz82S+)KUy;Xa7``L$r~gXE`$6tw9>ZkZA>{92^BE*#=vGtL@?T{5 zOiLG7$|;W3Pl0Wa{`Ptp-#c0h9e6EiX)%ktcTk%&j;+>`ad?=t{8lC9IO=3#0j_(= zAQ^x+;xKW@F>!!6LP1;^c-}_8QjMymzGGAz^f>P5O%LykJ=#BAkRxZb_$G>xOR+F= zSEOh=0P-+&?J2)2Tpc<&eFmf)(PJ=Zkh_xDk-weYb!p||%GHtBOU5=&&aI!ETRZXU zMz*w;D*bg^>HUKU9r+;Jdsl@1Zyzh`yN8dEZ7hT3GY995iocuesJCB+ODWZ}64Gt|cEbIt-q#6yj-a`2}F zFI_x-xLRKk?gL?{rJh}Kty;yNqQ_x5y0`y4G;n!A_>m0XA!9$0{ySvfPdFI+Md|x+ ss*(C7^T_8ffBpK}@YMHDZ)CKF@}~^1u0K1W>~D8s(b(P%PRIZ9561>^Z~y=R literal 0 HcmV?d00001 diff --git a/YakPanel-server/backend/scripts/seed_admin.py b/YakPanel-server/backend/scripts/seed_admin.py index b46b8bfc..f704d4bc 100644 --- a/YakPanel-server/backend/scripts/seed_admin.py +++ b/YakPanel-server/backend/scripts/seed_admin.py @@ -14,12 +14,19 @@ from app.core.security import get_password_hash from app.models.user import User -async def seed(): +async def seed(*, reset_password: bool = False): await init_db() async with AsyncSessionLocal() as db: result = await db.execute(select(User).where(User.username == "admin")) - if result.scalar_one_or_none(): - print("Admin user already exists") + existing = result.scalar_one_or_none() + if existing: + if reset_password: + existing.password = get_password_hash("admin") + existing.is_active = True + await db.commit() + print("Admin password reset: username=admin, password=admin") + else: + print("Admin user already exists (use --reset-password to force admin/admin)") return admin = User( username="admin", @@ -32,4 +39,5 @@ async def seed(): if __name__ == "__main__": - asyncio.run(seed()) + reset = "--reset-password" in sys.argv + asyncio.run(seed(reset_password=reset)) diff --git a/YakPanel-server/frontend/src/api/client.ts b/YakPanel-server/frontend/src/api/client.ts index 2f1adef1..fb4a5b89 100644 --- a/YakPanel-server/frontend/src/api/client.ts +++ b/YakPanel-server/frontend/src/api/client.ts @@ -1,5 +1,20 @@ const API_BASE = '/api/v1' +function formatFastApiDetail(detail: unknown): string | undefined { + if (typeof detail === 'string') return detail + if (Array.isArray(detail)) { + return detail + .map((item) => { + if (item && typeof item === 'object' && 'msg' in item) { + return String((item as { msg: string }).msg) + } + return JSON.stringify(item) + }) + .join('; ') + } + return undefined +} + export async function apiRequest( path: string, options: RequestInit = {} @@ -26,16 +41,26 @@ export async function apiRequest( } export async function login(username: string, password: string) { - const form = new FormData() - form.append('username', username) - form.append('password', password) + // OAuth2 password flow uses application/x-www-form-urlencoded (RFC 6749). + // multipart FormData can be mishandled by some proxies and is non-standard here. + const body = new URLSearchParams() + body.set('username', username) + body.set('password', password) const res = await fetch(`${API_BASE}/auth/login`, { method: 'POST', - body: form, + headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, + body: body.toString(), }) if (!res.ok) { - const err = await res.json().catch(() => ({})) - throw new Error(err.detail || `Login failed`) + const err = await res.json().catch(() => null) + const detail = err ? formatFastApiDetail(err.detail) : undefined + const msg = + detail || + (err && typeof (err as { message?: string }).message === 'string' + ? (err as { message: string }).message + : undefined) || + `Login failed (${res.status})` + throw new Error(msg) } const data = await res.json() localStorage.setItem('token', data.access_token)