1111from consts .exceptions import NoInviteCodeException , IncorrectInviteCodeException , UserRegistrationException
1212from services .user_management_service import get_authorized_client , validate_token , \
1313 check_auth_service_health , signup_user , signin_user , refresh_user_token , \
14- get_session_by_authorization
14+ get_session_by_authorization , revoke_regular_user
1515from consts .exceptions import UnauthorizedError
1616from utils .auth_utils import get_current_user_id
1717
@@ -69,7 +69,7 @@ async def signup(request: UserSignUpRequest):
6969 detail = "EMAIL_ALREADY_EXISTS" )
7070 except AuthWeakPasswordError as e :
7171 logging .error (f"User registration failed by weak password: { str (e )} " )
72- raise HTTPException (status_code = HTTPStatus .UNPROCESSABLE_ENTITY ,
72+ raise HTTPException (status_code = HTTPStatus .NOT_ACCEPTABLE ,
7373 detail = "WEAK_PASSWORD" )
7474 except Exception as e :
7575 logging .error (f"User registration failed, unknown error: { str (e )} " )
@@ -87,7 +87,7 @@ async def signin(request: UserSignInRequest):
8787 content = signin_content )
8888 except AuthApiError as e :
8989 logging .error (f"User login failed: { str (e )} " )
90- raise HTTPException (status_code = HTTPStatus .UNPROCESSABLE_ENTITY ,
90+ raise HTTPException (status_code = HTTPStatus .UNAUTHORIZED ,
9191 detail = "Email or password error" )
9292 except Exception as e :
9393 logging .error (f"User login failed, unknown error: { str (e )} " )
@@ -200,3 +200,48 @@ async def get_user_id(request: Request):
200200 logging .error (f"Get user ID failed: { str (e )} " )
201201 raise HTTPException (status_code = HTTPStatus .INTERNAL_SERVER_ERROR ,
202202 detail = "Get user ID failed" )
203+
204+
205+ @router .post ("/revoke" )
206+ async def revoke_user_account (request : Request ):
207+ """Delete current regular user's account and purge related data.
208+
209+ Notes:
210+ - Tenant admin (role=admin) is not allowed to be revoked via this endpoint.
211+ - Idempotent: local deletions are soft deletes; Supabase deletion may already have occurred.
212+ """
213+ authorization = request .headers .get ("Authorization" )
214+ if not authorization :
215+ raise HTTPException (status_code = HTTPStatus .UNAUTHORIZED ,
216+ detail = "No authorization token provided" )
217+ try :
218+ # Identify current user and tenant
219+ user_id , tenant_id = get_current_user_id (authorization )
220+
221+ # Determine role via token validation
222+ is_valid , user = validate_token (authorization .replace ("Bearer " , "" ))
223+ if not is_valid or not user :
224+ raise UnauthorizedError ("User not logged in or session invalid" )
225+
226+ # Extract role from user metadata
227+ user_role = "user"
228+ if getattr (user , "user_metadata" , None ) and 'role' in user .user_metadata :
229+ user_role = user .user_metadata ['role' ]
230+
231+ # Disallow admin revocation by this endpoint
232+ if user_role == "admin" :
233+ raise HTTPException (status_code = HTTPStatus .FORBIDDEN ,
234+ detail = "Admin account cannot be deleted via this endpoint" )
235+
236+ # Orchestrate revoke for regular user
237+ await revoke_regular_user (user_id = user_id , tenant_id = tenant_id )
238+
239+ return JSONResponse (status_code = HTTPStatus .OK , content = {"message" : "User account revoked" })
240+ except UnauthorizedError as e :
241+ raise HTTPException (status_code = HTTPStatus .UNAUTHORIZED , detail = str (e ))
242+ except HTTPException :
243+ raise
244+ except Exception as e :
245+ logging .error (f"User revoke failed: { str (e )} " )
246+ raise HTTPException (
247+ status_code = HTTPStatus .INTERNAL_SERVER_ERROR , detail = "User revoke failed" )
0 commit comments