Update the API to use new naming matching database.
This commit is contained in:
@@ -130,7 +130,7 @@ function parseHash() {
|
|||||||
async function loadOrgs() {
|
async function loadOrgs() {
|
||||||
const data = await apiJson('/auth/api/admin/orgs')
|
const data = await apiJson('/auth/api/admin/orgs')
|
||||||
orgs.value = data.map(o => {
|
orgs.value = data.map(o => {
|
||||||
const roles = o.roles.map(r => ({ ...r, org_uuid: o.uuid, users: [] }))
|
const roles = o.roles.map(r => ({ ...r, org: o.uuid, users: [] }))
|
||||||
const roleMap = Object.fromEntries(roles.map(r => [r.display_name, r]))
|
const roleMap = Object.fromEntries(roles.map(r => [r.display_name, r]))
|
||||||
for (const u of o.users || []) {
|
for (const u of o.users || []) {
|
||||||
if (roleMap[u.role]) roleMap[u.role].users.push(u)
|
if (roleMap[u.role]) roleMap[u.role].users.push(u)
|
||||||
@@ -242,9 +242,9 @@ async function moveUserToRole(org, user, targetRoleDisplayName) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onUserDragStart(e, user, org_uuid) {
|
function onUserDragStart(e, user, org) {
|
||||||
e.dataTransfer.effectAllowed = 'move'
|
e.dataTransfer.effectAllowed = 'move'
|
||||||
e.dataTransfer.setData('text/plain', JSON.stringify({ user_uuid: user.uuid, org_uuid }))
|
e.dataTransfer.setData('text/plain', JSON.stringify({ user_uuid: user.uuid, org }))
|
||||||
}
|
}
|
||||||
|
|
||||||
function onRoleDragOver(e) {
|
function onRoleDragOver(e) {
|
||||||
@@ -256,7 +256,7 @@ function onRoleDrop(e, org, role) {
|
|||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
try {
|
try {
|
||||||
const data = JSON.parse(e.dataTransfer.getData('text/plain'))
|
const data = JSON.parse(e.dataTransfer.getData('text/plain'))
|
||||||
if (data.org_uuid !== org.uuid) return // only within same org
|
if (data.org !== org.uuid) return // only within same org
|
||||||
const user = org.roles.flatMap(r => r.users).find(u => u.uuid === data.user_uuid)
|
const user = org.roles.flatMap(r => r.users).find(u => u.uuid === data.user_uuid)
|
||||||
if (user) moveUserToRole(org, user, role.display_name)
|
if (user) moveUserToRole(org, user, role.display_name)
|
||||||
} catch (_) { /* ignore */ }
|
} catch (_) { /* ignore */ }
|
||||||
@@ -269,7 +269,7 @@ function updateRole(role) { openDialog('role-update', { role, name: role.display
|
|||||||
|
|
||||||
function deleteRole(role) {
|
function deleteRole(role) {
|
||||||
// UI only allows deleting empty roles, so no confirmation needed
|
// UI only allows deleting empty roles, so no confirmation needed
|
||||||
apiJson(`/auth/api/admin/orgs/${role.org_uuid}/roles/${role.uuid}`, { method: 'DELETE' })
|
apiJson(`/auth/api/admin/orgs/${role.org}/roles/${role.uuid}`, { method: 'DELETE' })
|
||||||
.then(() => {
|
.then(() => {
|
||||||
authStore.showMessage(`Role "${role.display_name}" deleted.`, 'success', 2500)
|
authStore.showMessage(`Role "${role.display_name}" deleted.`, 'success', 2500)
|
||||||
loadOrgs()
|
loadOrgs()
|
||||||
@@ -289,7 +289,7 @@ async function toggleRolePermission(role, pid, checked) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const method = checked ? 'POST' : 'DELETE'
|
const method = checked ? 'POST' : 'DELETE'
|
||||||
await apiJson(`/auth/api/admin/orgs/${role.org_uuid}/roles/${role.uuid}/permissions/${pid}`, {
|
await apiJson(`/auth/api/admin/orgs/${role.org}/roles/${role.uuid}/permissions/${pid}`, {
|
||||||
method
|
method
|
||||||
})
|
})
|
||||||
await loadOrgs()
|
await loadOrgs()
|
||||||
@@ -360,7 +360,7 @@ const selectedUser = computed(() => {
|
|||||||
for (const o of orgs.value) {
|
for (const o of orgs.value) {
|
||||||
for (const r of o.roles) {
|
for (const r of o.roles) {
|
||||||
const u = r.users.find(x => x.uuid === currentUserId.value)
|
const u = r.users.find(x => x.uuid === currentUserId.value)
|
||||||
if (u) return { ...u, org_uuid: o.uuid, role_display_name: r.display_name }
|
if (u) return { ...u, org: o.uuid, role_display_name: r.display_name }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
@@ -381,7 +381,7 @@ const breadcrumbEntries = computed(() => {
|
|||||||
// Determine organization for user view if selectedOrg not explicitly chosen.
|
// Determine organization for user view if selectedOrg not explicitly chosen.
|
||||||
let orgForUser = null
|
let orgForUser = null
|
||||||
if (selectedUser.value) {
|
if (selectedUser.value) {
|
||||||
orgForUser = orgs.value.find(o => o.uuid === selectedUser.value.org_uuid) || null
|
orgForUser = orgs.value.find(o => o.uuid === selectedUser.value.org) || null
|
||||||
}
|
}
|
||||||
const orgToShow = selectedOrg.value || orgForUser
|
const orgToShow = selectedOrg.value || orgForUser
|
||||||
if (orgToShow) {
|
if (orgToShow) {
|
||||||
@@ -396,7 +396,7 @@ const breadcrumbEntries = computed(() => {
|
|||||||
watch(selectedUser, async (u) => {
|
watch(selectedUser, async (u) => {
|
||||||
if (!u) { userDetail.value = null; return }
|
if (!u) { userDetail.value = null; return }
|
||||||
try {
|
try {
|
||||||
userDetail.value = await apiJson(`/auth/api/admin/orgs/${u.org_uuid}/users/${u.uuid}`)
|
userDetail.value = await apiJson(`/auth/api/admin/orgs/${u.org}/users/${u.uuid}`)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
userDetail.value = { error: e.message }
|
userDetail.value = { error: e.message }
|
||||||
}
|
}
|
||||||
@@ -532,7 +532,7 @@ async function refreshUserDetail() {
|
|||||||
await loadOrgs()
|
await loadOrgs()
|
||||||
if (selectedUser.value) {
|
if (selectedUser.value) {
|
||||||
try {
|
try {
|
||||||
userDetail.value = await apiJson(`/auth/api/admin/orgs/${selectedUser.value.org_uuid}/users/${selectedUser.value.uuid}`)
|
userDetail.value = await apiJson(`/auth/api/admin/orgs/${selectedUser.value.org}/users/${selectedUser.value.uuid}`)
|
||||||
} catch (e) { authStore.showMessage(e.message || 'Failed to reload user', 'error') }
|
} catch (e) { authStore.showMessage(e.message || 'Failed to reload user', 'error') }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -594,7 +594,7 @@ async function submitDialog() {
|
|||||||
|
|
||||||
// Close dialog immediately, then perform async operation
|
// Close dialog immediately, then perform async operation
|
||||||
closeDialog()
|
closeDialog()
|
||||||
apiJson(`/auth/api/admin/orgs/${role.org_uuid}/roles/${role.uuid}`, { method: 'PATCH', body: { display_name: name } })
|
apiJson(`/auth/api/admin/orgs/${role.org}/roles/${role.uuid}`, { method: 'PATCH', body: { display_name: name } })
|
||||||
.then(() => {
|
.then(() => {
|
||||||
authStore.showMessage(`Role renamed to "${name}".`, 'success', 2500)
|
authStore.showMessage(`Role renamed to "${name}".`, 'success', 2500)
|
||||||
loadOrgs()
|
loadOrgs()
|
||||||
@@ -622,7 +622,7 @@ async function submitDialog() {
|
|||||||
|
|
||||||
// Close dialog immediately, then perform async operation
|
// Close dialog immediately, then perform async operation
|
||||||
closeDialog()
|
closeDialog()
|
||||||
apiJson(`/auth/api/admin/orgs/${user.org_uuid}/users/${user.uuid}/display-name`, { method: 'PATCH', body: { display_name: name } })
|
apiJson(`/auth/api/admin/orgs/${user.org}/users/${user.uuid}/display-name`, { method: 'PATCH', body: { display_name: name } })
|
||||||
.then(() => {
|
.then(() => {
|
||||||
authStore.showMessage(`User renamed to "${name}".`, 'success', 2500)
|
authStore.showMessage(`User renamed to "${name}".`, 'success', 2500)
|
||||||
onUserNameSaved()
|
onUserNameSaved()
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ function handleEditName() {
|
|||||||
|
|
||||||
async function handleDelete(credential) {
|
async function handleDelete(credential) {
|
||||||
try {
|
try {
|
||||||
const data = await apiJson(`/auth/api/admin/orgs/${props.selectedUser.org_uuid}/users/${props.selectedUser.uuid}/credentials/${credential.credential_uuid}`, { method: 'DELETE' })
|
const data = await apiJson(`/auth/api/admin/orgs/${props.selectedUser.org}/users/${props.selectedUser.uuid}/credentials/${credential.credential}`, { method: 'DELETE' })
|
||||||
if (data.status === 'ok') {
|
if (data.status === 'ok') {
|
||||||
emit('onUserNameSaved') // Reuse to refresh user detail
|
emit('onUserNameSaved') // Reuse to refresh user detail
|
||||||
} else {
|
} else {
|
||||||
@@ -61,7 +61,7 @@ async function handleTerminateSession(session) {
|
|||||||
if (!sessionId) return
|
if (!sessionId) return
|
||||||
terminatingSessions.value = { ...terminatingSessions.value, [sessionId]: true }
|
terminatingSessions.value = { ...terminatingSessions.value, [sessionId]: true }
|
||||||
try {
|
try {
|
||||||
const data = await apiJson(`/auth/api/admin/orgs/${props.selectedUser.org_uuid}/users/${props.selectedUser.uuid}/sessions/${sessionId}`, { method: 'DELETE' })
|
const data = await apiJson(`/auth/api/admin/orgs/${props.selectedUser.org}/users/${props.selectedUser.uuid}/sessions/${sessionId}`, { method: 'DELETE' })
|
||||||
if (data.status === 'ok') {
|
if (data.status === 'ok') {
|
||||||
if (data.current_session_terminated) {
|
if (data.current_session_terminated) {
|
||||||
sessionStorage.clear()
|
sessionStorage.clear()
|
||||||
@@ -183,7 +183,7 @@ defineExpose({ focusFirstElement })
|
|||||||
:loading="loading"
|
:loading="loading"
|
||||||
:org-display-name="userDetail.org.display_name"
|
:org-display-name="userDetail.org.display_name"
|
||||||
:role-name="userDetail.role"
|
:role-name="userDetail.role"
|
||||||
:update-endpoint="`/auth/api/admin/orgs/${selectedUser.org_uuid}/users/${selectedUser.uuid}/display-name`"
|
:update-endpoint="`/auth/api/admin/orgs/${selectedUser.org}/users/${selectedUser.uuid}/display-name`"
|
||||||
@saved="$emit('onUserNameSaved')"
|
@saved="$emit('onUserNameSaved')"
|
||||||
@edit-name="handleEditName"
|
@edit-name="handleEditName"
|
||||||
/>
|
/>
|
||||||
@@ -212,7 +212,7 @@ defineExpose({ focusFirstElement })
|
|||||||
:aaguid-info="userDetail.aaguid_info"
|
:aaguid-info="userDetail.aaguid_info"
|
||||||
:allow-delete="true"
|
:allow-delete="true"
|
||||||
:hovered-credential-uuid="hoveredCredentialUuid"
|
:hovered-credential-uuid="hoveredCredentialUuid"
|
||||||
:hovered-session-credential-uuid="hoveredSession?.credential_uuid"
|
:hovered-session-credential-uuid="hoveredSession?.credential"
|
||||||
:navigation-disabled="hasActiveModal"
|
:navigation-disabled="hasActiveModal"
|
||||||
@delete="handleDelete"
|
@delete="handleDelete"
|
||||||
@credential-hover="hoveredCredentialUuid = $event"
|
@credential-hover="hoveredCredentialUuid = $event"
|
||||||
@@ -238,7 +238,7 @@ defineExpose({ focusFirstElement })
|
|||||||
</div>
|
</div>
|
||||||
<RegistrationLinkModal
|
<RegistrationLinkModal
|
||||||
v-if="showRegModal"
|
v-if="showRegModal"
|
||||||
:endpoint="`/auth/api/admin/orgs/${selectedUser.org_uuid}/users/${selectedUser.uuid}/create-link`"
|
:endpoint="`/auth/api/admin/orgs/${selectedUser.org}/users/${selectedUser.uuid}/create-link`"
|
||||||
:user-name="userDetail?.display_name || selectedUser.display_name"
|
:user-name="userDetail?.display_name || selectedUser.display_name"
|
||||||
@close="$emit('closeRegModal')"
|
@close="$emit('closeRegModal')"
|
||||||
@copied="onLinkCopied"
|
@copied="onLinkCopied"
|
||||||
|
|||||||
@@ -5,16 +5,16 @@
|
|||||||
<template v-else>
|
<template v-else>
|
||||||
<div
|
<div
|
||||||
v-for="credential in credentials"
|
v-for="credential in credentials"
|
||||||
:key="credential.credential_uuid"
|
:key="credential.credential"
|
||||||
:class="['credential-item', {
|
:class="['credential-item', {
|
||||||
'current-session': credential.is_current_session && !hoveredCredentialUuid && !hoveredSessionCredentialUuid,
|
'current-session': credential.is_current_session && !hoveredCredentialUuid && !hoveredSessionCredentialUuid,
|
||||||
'is-hovered': hoveredCredentialUuid === credential.credential_uuid,
|
'is-hovered': hoveredCredentialUuid === credential.credential,
|
||||||
'is-linked-session': hoveredSessionCredentialUuid === credential.credential_uuid
|
'is-linked-session': hoveredSessionCredentialUuid === credential.credential
|
||||||
}]"
|
}]"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
@mousedown.prevent
|
@mousedown.prevent
|
||||||
@click.capture="handleCardClick"
|
@click.capture="handleCardClick"
|
||||||
@focusin="handleCredentialFocus(credential.credential_uuid)"
|
@focusin="handleCredentialFocus(credential.credential)"
|
||||||
@focusout="handleCredentialBlur($event)"
|
@focusout="handleCredentialBlur($event)"
|
||||||
@keydown="handleItemKeydown($event, credential)"
|
@keydown="handleItemKeydown($event, credential)"
|
||||||
>
|
>
|
||||||
@@ -33,8 +33,8 @@
|
|||||||
<h4 class="item-title">{{ getCredentialAuthName(credential) }}</h4>
|
<h4 class="item-title">{{ getCredentialAuthName(credential) }}</h4>
|
||||||
<div class="item-actions">
|
<div class="item-actions">
|
||||||
<span v-if="credential.is_current_session && !hoveredCredentialUuid && !hoveredSessionCredentialUuid" class="badge badge-current">Current</span>
|
<span v-if="credential.is_current_session && !hoveredCredentialUuid && !hoveredSessionCredentialUuid" class="badge badge-current">Current</span>
|
||||||
<span v-else-if="hoveredCredentialUuid === credential.credential_uuid" class="badge badge-current">Selected</span>
|
<span v-else-if="hoveredCredentialUuid === credential.credential" class="badge badge-current">Selected</span>
|
||||||
<span v-else-if="hoveredSessionCredentialUuid === credential.credential_uuid" class="badge badge-current">Linked</span>
|
<span v-else-if="hoveredSessionCredentialUuid === credential.credential" class="badge badge-current">Linked</span>
|
||||||
<button
|
<button
|
||||||
v-if="allowDelete"
|
v-if="allowDelete"
|
||||||
@click="$emit('delete', credential)"
|
@click="$emit('delete', credential)"
|
||||||
|
|||||||
@@ -47,7 +47,7 @@
|
|||||||
:aaguid-info="authStore.userInfo?.aaguid_info || {}"
|
:aaguid-info="authStore.userInfo?.aaguid_info || {}"
|
||||||
:loading="authStore.isLoading"
|
:loading="authStore.isLoading"
|
||||||
:hovered-credential-uuid="hoveredCredentialUuid"
|
:hovered-credential-uuid="hoveredCredentialUuid"
|
||||||
:hovered-session-credential-uuid="hoveredSession?.credential_uuid"
|
:hovered-session-credential-uuid="hoveredSession?.credential"
|
||||||
:navigation-disabled="hasActiveModal"
|
:navigation-disabled="hasActiveModal"
|
||||||
allow-delete
|
allow-delete
|
||||||
@delete="handleDelete"
|
@delete="handleDelete"
|
||||||
@@ -292,7 +292,7 @@ const handleLogoutButtonKeydown = (event) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleDelete = async (credential) => {
|
const handleDelete = async (credential) => {
|
||||||
const credentialId = credential?.credential_uuid
|
const credentialId = credential?.credential
|
||||||
if (!credentialId) return
|
if (!credentialId) return
|
||||||
try {
|
try {
|
||||||
await authStore.deleteCredential(credentialId)
|
await authStore.deleteCredential(credentialId)
|
||||||
|
|||||||
@@ -279,7 +279,7 @@ onUnmounted(() => {
|
|||||||
defineExpose({
|
defineExpose({
|
||||||
showMessage,
|
showMessage,
|
||||||
isAuthenticated,
|
isAuthenticated,
|
||||||
userInfo
|
session
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
:class="['session-item', {
|
:class="['session-item', {
|
||||||
'is-current': session.is_current && !hoveredIp && !hoveredCredentialUuid,
|
'is-current': session.is_current && !hoveredIp && !hoveredCredentialUuid,
|
||||||
'is-hovered': hoveredSession?.id === session.id,
|
'is-hovered': hoveredSession?.id === session.id,
|
||||||
'is-linked-credential': hoveredCredentialUuid === session.credential_uuid
|
'is-linked-credential': hoveredCredentialUuid === session.credential
|
||||||
}]"
|
}]"
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
@mousedown.prevent
|
@mousedown.prevent
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
<div class="item-actions">
|
<div class="item-actions">
|
||||||
<span v-if="session.is_current && !hoveredIp && !hoveredCredentialUuid" class="badge badge-current">Current</span>
|
<span v-if="session.is_current && !hoveredIp && !hoveredCredentialUuid" class="badge badge-current">Current</span>
|
||||||
<span v-else-if="hoveredSession?.id === session.id" class="badge badge-current">Selected</span>
|
<span v-else-if="hoveredSession?.id === session.id" class="badge badge-current">Selected</span>
|
||||||
<span v-else-if="hoveredCredentialUuid === session.credential_uuid" class="badge badge-current">Linked</span>
|
<span v-else-if="hoveredCredentialUuid === session.credential" class="badge badge-current">Linked</span>
|
||||||
<span v-else-if="!hoveredCredentialUuid && isSameHost(session.ip)" class="badge">Same IP</span>
|
<span v-else-if="!hoveredCredentialUuid && isSameHost(session.ip)" class="badge">Same IP</span>
|
||||||
<button
|
<button
|
||||||
@click="$emit('terminate', session)"
|
@click="$emit('terminate', session)"
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ async def admin_list_orgs(request: Request, auth=AUTH_COOKIE):
|
|||||||
def role_to_dict(r):
|
def role_to_dict(r):
|
||||||
return {
|
return {
|
||||||
"uuid": str(r.uuid),
|
"uuid": str(r.uuid),
|
||||||
"org_uuid": str(r.org_uuid),
|
"org": str(r.org),
|
||||||
"display_name": r.display_name,
|
"display_name": r.display_name,
|
||||||
"permissions": r.permissions,
|
"permissions": r.permissions,
|
||||||
}
|
}
|
||||||
@@ -600,7 +600,7 @@ async def admin_get_user_detail(
|
|||||||
aaguids.add(aaguid_str)
|
aaguids.add(aaguid_str)
|
||||||
creds.append(
|
creds.append(
|
||||||
{
|
{
|
||||||
"credential_uuid": str(c.uuid),
|
"credential": str(c.uuid),
|
||||||
"aaguid": aaguid_str,
|
"aaguid": aaguid_str,
|
||||||
"created_at": (
|
"created_at": (
|
||||||
c.created_at.astimezone(timezone.utc)
|
c.created_at.astimezone(timezone.utc)
|
||||||
@@ -656,7 +656,7 @@ async def admin_get_user_detail(
|
|||||||
sessions_payload.append(
|
sessions_payload.append(
|
||||||
{
|
{
|
||||||
"id": entry.key,
|
"id": entry.key,
|
||||||
"credential_uuid": str(entry.credential_uuid),
|
"credential": str(entry.credential),
|
||||||
"host": entry.host,
|
"host": entry.host,
|
||||||
"ip": entry.ip,
|
"ip": entry.ip,
|
||||||
"user_agent": useragent.compact_user_agent(entry.user_agent),
|
"user_agent": useragent.compact_user_agent(entry.user_agent),
|
||||||
|
|||||||
@@ -268,5 +268,5 @@ async def api_set_session(
|
|||||||
session.set_session_cookie(response, auth.credentials)
|
session.set_session_cookie(response, auth.credentials)
|
||||||
return {
|
return {
|
||||||
"message": "Session cookie set successfully",
|
"message": "Session cookie set successfully",
|
||||||
"user_uuid": str(user.user_uuid),
|
"user": str(user.user),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ async def websocket_remote_auth_request(ws: WebSocket):
|
|||||||
):
|
):
|
||||||
response = {
|
response = {
|
||||||
"status": "authenticated",
|
"status": "authenticated",
|
||||||
"user_uuid": str(result_data["user_uuid"]),
|
"user": str(result_data["user_uuid"]),
|
||||||
}
|
}
|
||||||
if result_data.get("session_token"):
|
if result_data.get("session_token"):
|
||||||
response["session_token"] = result_data["session_token"]
|
response["session_token"] = result_data["session_token"]
|
||||||
|
|||||||
@@ -93,8 +93,8 @@ async def websocket_register_add(
|
|||||||
assert isinstance(auth, str) and len(auth) == 16
|
assert isinstance(auth, str) and len(auth) == 16
|
||||||
await ws.send_json(
|
await ws.send_json(
|
||||||
{
|
{
|
||||||
"user_uuid": str(user.uuid),
|
"user": str(user.uuid),
|
||||||
"credential_uuid": str(credential.uuid),
|
"credential": str(credential.uuid),
|
||||||
"session_token": auth,
|
"session_token": auth,
|
||||||
"message": "New credential added successfully",
|
"message": "New credential added successfully",
|
||||||
}
|
}
|
||||||
@@ -164,7 +164,7 @@ async def websocket_authenticate(ws: WebSocket, auth=AUTH_COOKIE):
|
|||||||
|
|
||||||
await ws.send_json(
|
await ws.send_json(
|
||||||
{
|
{
|
||||||
"user_uuid": str(stored_cred.user),
|
"user": str(stored_cred.user),
|
||||||
"session_token": token,
|
"session_token": token,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -57,13 +57,13 @@ async def format_user_info(
|
|||||||
user_aaguids.add(aaguid_str)
|
user_aaguids.add(aaguid_str)
|
||||||
credentials.append(
|
credentials.append(
|
||||||
{
|
{
|
||||||
"credential_uuid": str(c.uuid),
|
"credential": str(c.uuid),
|
||||||
"aaguid": aaguid_str,
|
"aaguid": aaguid_str,
|
||||||
"created_at": _format_datetime(c.created_at),
|
"created_at": _format_datetime(c.created_at),
|
||||||
"last_used": _format_datetime(c.last_used),
|
"last_used": _format_datetime(c.last_used),
|
||||||
"last_verified": _format_datetime(c.last_verified),
|
"last_verified": _format_datetime(c.last_verified),
|
||||||
"sign_count": c.sign_count,
|
"sign_count": c.sign_count,
|
||||||
"is_current_session": session_record.credential_uuid == c.uuid,
|
"is_current_session": session_record.credential == c.uuid,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ async def format_user_info(
|
|||||||
sessions_payload.append(
|
sessions_payload.append(
|
||||||
{
|
{
|
||||||
"id": entry.key,
|
"id": entry.key,
|
||||||
"credential_uuid": str(entry.credential_uuid),
|
"credential": str(entry.credential),
|
||||||
"host": entry.host,
|
"host": entry.host,
|
||||||
"ip": entry.ip,
|
"ip": entry.ip,
|
||||||
"user_agent": useragent.compact_user_agent(entry.user_agent),
|
"user_agent": useragent.compact_user_agent(entry.user_agent),
|
||||||
|
|||||||
+1
-1
@@ -317,7 +317,7 @@ class TestSetSessionEndpoint:
|
|||||||
)
|
)
|
||||||
assert response.status_code == 200
|
assert response.status_code == 200
|
||||||
data = response.json()
|
data = response.json()
|
||||||
assert "user_uuid" in data
|
assert "user" in data
|
||||||
# Check that Set-Cookie header is present
|
# Check that Set-Cookie header is present
|
||||||
assert "set-cookie" in response.headers
|
assert "set-cookie" in response.headers
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user