/* * server component for the TimeLimit App * Copyright (C) 2019 - 2026 Jonas Lochmann * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ import { Conflict, Unauthorized } from 'http-errors' import { SimpleDatabase } from '../../database/simple' import { WebsocketApi } from '../../websocket' export const logoutAtPrimaryDevice = async ({ deviceAuthToken, database, websocket }: { deviceAuthToken: string database: SimpleDatabase websocket: WebsocketApi // no transaction here because this is directly called from an API endpoint }) => { await database.transaction(async (transaction) => { const ownDeviceEntryUnsafe = await transaction.legacy.database.device.findOne({ where: { deviceAuthToken }, transaction: transaction.legacy.transaction, attributes: ['familyId', 'currentUserId', 'deviceId'] }) if (!ownDeviceEntryUnsafe) { throw new Unauthorized() } const ownDeviceEntry = { familyId: ownDeviceEntryUnsafe.familyId, currentUserId: ownDeviceEntryUnsafe.currentUserId } const deviceUserEntryUnsafe = await transaction.legacy.database.user.findOne({ where: { familyId: ownDeviceEntry.familyId, userId: ownDeviceEntry.currentUserId, type: 'child' }, attributes: ['currentDevice'], transaction: transaction.legacy.transaction }) if (!deviceUserEntryUnsafe) { throw new Conflict() } const deviceUserEntry = { currentDevice: deviceUserEntryUnsafe.currentDevice } const otherDeviceEntryUnsafe = await transaction.legacy.database.device.findOne({ where: { familyId: ownDeviceEntry.familyId, deviceId: deviceUserEntry.currentDevice, currentUserId: ownDeviceEntry.currentUserId }, attributes: ['deviceAuthToken'], transaction: transaction.legacy.transaction }) if (!otherDeviceEntryUnsafe) { throw new Conflict() } const otherDeviceEntry = { deviceAuthToken: otherDeviceEntryUnsafe.deviceAuthToken } websocket.triggerLogoutByDeviceAuthToken({ deviceAuthToken: otherDeviceEntry.deviceAuthToken }) }) }