revoke_self and revoke_device each loaded the caller's DeviceToken, deleted it, committed and audited DEVICE_UNLINKED; _unlink_device(which) is that, owner-scoped as before, with each route keeping only how it names the row. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+9
-18
@@ -659,21 +659,9 @@ async def revoke_own_device():
|
||||
# using" is meaningless rather than merely unauthorized. The web app
|
||||
# revokes by id.
|
||||
return json_error("no device token was presented", 400)
|
||||
async with session_scope() as db:
|
||||
row = await db.scalar(
|
||||
select(DeviceToken).where(
|
||||
DeviceToken.token_hash == hash_token(token),
|
||||
# Owner-scoped like every other device route. The hash already pins
|
||||
# a single row; the guarantee shouldn't rest on one column.
|
||||
DeviceToken.user_id == g.user_id,
|
||||
)
|
||||
)
|
||||
if row is None:
|
||||
return not_found()
|
||||
await db.delete(row)
|
||||
await db.commit()
|
||||
await audit.record(audit.DEVICE_UNLINKED, user_id=g.user_id, email=await _email_of(db), detail=row.name)
|
||||
return jsonify({"ok": True})
|
||||
# Owner-scoped like every other device route. The hash already pins a single
|
||||
# row; the guarantee shouldn't rest on one column.
|
||||
return await _unlink_device(DeviceToken.token_hash == hash_token(token))
|
||||
|
||||
|
||||
@bp.delete("/devices/<device_id>")
|
||||
@@ -682,10 +670,13 @@ async def revoke_device(device_id: str):
|
||||
did = parse_uuid(device_id)
|
||||
if did is None:
|
||||
return not_found()
|
||||
return await _unlink_device(DeviceToken.id == did)
|
||||
|
||||
|
||||
async def _unlink_device(which):
|
||||
"""Delete the caller's device token matching `which`, and say so in the audit log."""
|
||||
async with session_scope() as db:
|
||||
row = await db.scalar(
|
||||
select(DeviceToken).where(DeviceToken.id == did, DeviceToken.user_id == g.user_id)
|
||||
)
|
||||
row = await db.scalar(select(DeviceToken).where(which, DeviceToken.user_id == g.user_id))
|
||||
if row is None:
|
||||
return not_found()
|
||||
await db.delete(row)
|
||||
|
||||
Reference in New Issue
Block a user