reversion
parent
e6d2cffddb
commit
8284ccf05e
|
|
@ -8,6 +8,7 @@ from users.views import User
|
||||||
from users.permissions import CurrentUser, PermissionTag, require_permission
|
from users.permissions import CurrentUser, PermissionTag, require_permission
|
||||||
from users.serializers import serialize_token
|
from users.serializers import serialize_token
|
||||||
from users.plugins import create_access_token,create_refresh_token
|
from users.plugins import create_access_token,create_refresh_token
|
||||||
|
from role.models import Roles
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
|
|
@ -60,7 +61,13 @@ async def login(payload: UserLogin,session: AsyncSession = Depends(get_session))
|
||||||
try:
|
try:
|
||||||
service=User(session=session)
|
service=User(session=session)
|
||||||
user=await service.authenticate_user(payload.email or payload.username,payload.password)
|
user=await service.authenticate_user(payload.email or payload.username,payload.password)
|
||||||
tokens=serialize_token(create_access_token(user),create_refresh_token(user),user)
|
permissions=await Roles.resolve_tags(session,user.role)
|
||||||
|
tokens=serialize_token(
|
||||||
|
create_access_token(user),
|
||||||
|
create_refresh_token(user),
|
||||||
|
user,
|
||||||
|
permissions=permissions,
|
||||||
|
)
|
||||||
return JSONResponse(content={**tokens,"status_code":200})
|
return JSONResponse(content={**tokens,"status_code":200})
|
||||||
except HTTPException:
|
except HTTPException:
|
||||||
raise
|
raise
|
||||||
|
|
@ -73,7 +80,13 @@ async def signup(payload: UserSignup,session: AsyncSession = Depends(get_session
|
||||||
try:
|
try:
|
||||||
service=User(session=session)
|
service=User(session=session)
|
||||||
user=await service.signup_user(payload.model_dump())
|
user=await service.signup_user(payload.model_dump())
|
||||||
tokens=serialize_token(create_access_token(user),create_refresh_token(user),user)
|
permissions=await Roles.resolve_tags(session,user.role)
|
||||||
|
tokens=serialize_token(
|
||||||
|
create_access_token(user),
|
||||||
|
create_refresh_token(user),
|
||||||
|
user,
|
||||||
|
permissions=permissions,
|
||||||
|
)
|
||||||
return JSONResponse(content={**tokens,"status_code":200})
|
return JSONResponse(content={**tokens,"status_code":200})
|
||||||
except HTTPException:
|
except HTTPException:
|
||||||
raise
|
raise
|
||||||
|
|
@ -86,7 +99,13 @@ async def refresh(payload: TokenRefresh,session: AsyncSession = Depends(get_sess
|
||||||
try:
|
try:
|
||||||
service=User(session=session)
|
service=User(session=session)
|
||||||
user=await service.refresh_access_token(payload.refresh_token)
|
user=await service.refresh_access_token(payload.refresh_token)
|
||||||
tokens=serialize_token(create_access_token(user),create_refresh_token(user),user)
|
permissions=await Roles.resolve_tags(session,user.role)
|
||||||
|
tokens=serialize_token(
|
||||||
|
create_access_token(user),
|
||||||
|
create_refresh_token(user),
|
||||||
|
user,
|
||||||
|
permissions=permissions,
|
||||||
|
)
|
||||||
return JSONResponse(content={**tokens,"status_code":200})
|
return JSONResponse(content={**tokens,"status_code":200})
|
||||||
except HTTPException:
|
except HTTPException:
|
||||||
raise
|
raise
|
||||||
|
|
|
||||||
|
|
@ -33,12 +33,24 @@ def serialize_user(
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
def serialize_token(access_token: str, refresh_token: str, user: Users) -> dict:
|
def serialize_token(
|
||||||
"""Login/refresh payload. OAuth2 fields live at the root so Swagger's Authorize can read them."""
|
access_token: str,
|
||||||
|
refresh_token: str,
|
||||||
|
user: Users,
|
||||||
|
*,
|
||||||
|
permissions: tuple[str, ...] | list[str] | None = None,
|
||||||
|
) -> dict:
|
||||||
|
"""Login/refresh payload. OAuth2 fields live at the root so Swagger's Authorize can read them.
|
||||||
|
|
||||||
|
Always include resolved permissions so the SPA can paint the nav before
|
||||||
|
GET /users/me returns (and so a stale localStorage role cannot linger).
|
||||||
|
"""
|
||||||
return {
|
return {
|
||||||
"access_token": access_token,
|
"access_token": access_token,
|
||||||
"refresh_token": refresh_token,
|
"refresh_token": refresh_token,
|
||||||
"token_type": "bearer",
|
"token_type": "bearer",
|
||||||
"expires_in": ACCESS_TOKEN_EXPIRE_SECONDS,
|
"expires_in": ACCESS_TOKEN_EXPIRE_SECONDS,
|
||||||
"data": serialize_user(user),
|
"data": serialize_user(
|
||||||
|
user, with_permissions=True, permissions=permissions or ()
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,12 +79,20 @@ export function isExpiring(skew = CLOCK_SKEW_MS) {
|
||||||
* mid-session.
|
* mid-session.
|
||||||
*/
|
*/
|
||||||
export function setSession(res) {
|
export function setSession(res) {
|
||||||
|
const incoming = res.data ?? {}
|
||||||
|
const prev = cached?.data ?? {}
|
||||||
cached = {
|
cached = {
|
||||||
access_token: res.access_token,
|
access_token: res.access_token,
|
||||||
refresh_token: res.refresh_token,
|
refresh_token: res.refresh_token,
|
||||||
expires_in: res.expires_in,
|
expires_in: res.expires_in,
|
||||||
expires_at: Date.now() + (res.expires_in ?? 1800) * 1000,
|
expires_at: Date.now() + (res.expires_in ?? 1800) * 1000,
|
||||||
data: { ...(cached?.data ?? {}), ...(res.data ?? {}) },
|
// Keep prior permissions when a token response omits them (legacy refresh);
|
||||||
|
// when login/me includes permissions, those win.
|
||||||
|
data: {
|
||||||
|
...prev,
|
||||||
|
...incoming,
|
||||||
|
permissions: incoming.permissions ?? prev.permissions,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
persist()
|
persist()
|
||||||
emit()
|
emit()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue