new changes

This commit is contained in:
Niranjan
2026-04-07 03:57:44 +05:30
parent 3872d90ee7
commit 73148d2b09
4 changed files with 43 additions and 10 deletions

View File

@@ -14,12 +14,19 @@ from app.core.security import get_password_hash
from app.models.user import User from app.models.user import User
async def seed(): async def seed(*, reset_password: bool = False):
await init_db() await init_db()
async with AsyncSessionLocal() as db: async with AsyncSessionLocal() as db:
result = await db.execute(select(User).where(User.username == "admin")) result = await db.execute(select(User).where(User.username == "admin"))
if result.scalar_one_or_none(): existing = result.scalar_one_or_none()
print("Admin user already exists") 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 return
admin = User( admin = User(
username="admin", username="admin",
@@ -32,4 +39,5 @@ async def seed():
if __name__ == "__main__": if __name__ == "__main__":
asyncio.run(seed()) reset = "--reset-password" in sys.argv
asyncio.run(seed(reset_password=reset))

View File

@@ -1,5 +1,20 @@
const API_BASE = '/api/v1' 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<T>( export async function apiRequest<T>(
path: string, path: string,
options: RequestInit = {} options: RequestInit = {}
@@ -26,16 +41,26 @@ export async function apiRequest<T>(
} }
export async function login(username: string, password: string) { export async function login(username: string, password: string) {
const form = new FormData() // OAuth2 password flow uses application/x-www-form-urlencoded (RFC 6749).
form.append('username', username) // multipart FormData can be mishandled by some proxies and is non-standard here.
form.append('password', password) const body = new URLSearchParams()
body.set('username', username)
body.set('password', password)
const res = await fetch(`${API_BASE}/auth/login`, { const res = await fetch(`${API_BASE}/auth/login`, {
method: 'POST', method: 'POST',
body: form, headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: body.toString(),
}) })
if (!res.ok) { if (!res.ok) {
const err = await res.json().catch(() => ({})) const err = await res.json().catch(() => null)
throw new Error(err.detail || `Login failed`) 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() const data = await res.json()
localStorage.setItem('token', data.access_token) localStorage.setItem('token', data.access_token)