mirror of
https://codeberg.org/timelimit/timelimit-server.git
synced 2026-08-31 19:03:45 +02:00
Add ping support
This commit is contained in:
+2
-1
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* server component for the TimeLimit App
|
||||
* Copyright (C) 2019 - 2022 Jonas Lochmann
|
||||
* 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
|
||||
@@ -78,6 +78,7 @@ export { UpdateTimelimitRuleAction } from './updatetimelimitrule'
|
||||
export { UpdateUserFlagsAction } from './updateuserflags'
|
||||
export { UpdateUserLimitLoginCategory } from './updateuserlimitlogincategory'
|
||||
export { MarkTaskPendingAction } from './marktaskpendingaction'
|
||||
export { PingAction } from './ping'
|
||||
export { DeleteChildTaskAction } from './deletechildtaskaction'
|
||||
export { UpdateChildTaskAction } from './updatechildtaskaction'
|
||||
export { ReviewChildTaskAction } from './reviewchildtaskaction'
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { AppLogicAction } from './basetypes'
|
||||
import { assertIdWithinFamily } from './meta/util'
|
||||
|
||||
const actionType = 'PingAction'
|
||||
|
||||
export class PingAction extends AppLogicAction {
|
||||
readonly deviceId: string
|
||||
readonly event: PingEvent
|
||||
readonly token: string
|
||||
|
||||
constructor ({ deviceId, event, token }: {
|
||||
deviceId: string
|
||||
event: PingEvent
|
||||
token: string
|
||||
}) {
|
||||
super()
|
||||
|
||||
assertIdWithinFamily({ actionType, field: 'deviceId', value: deviceId })
|
||||
assertIdWithinFamily({ actionType, field: 'token', value: token })
|
||||
|
||||
this.deviceId = deviceId
|
||||
this.event = event
|
||||
this.token = token
|
||||
}
|
||||
|
||||
static parse = ({ deviceId, event, token }: SerializedPingAction) => (
|
||||
new PingAction({ deviceId, event, token })
|
||||
)
|
||||
}
|
||||
|
||||
export interface SerializedPingAction {
|
||||
type: 'PING'
|
||||
deviceId: string
|
||||
event: PingEvent
|
||||
token: string
|
||||
}
|
||||
|
||||
export type PingEvent = 'ping' | 'pong' | 'clear'
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* server component for the TimeLimit App
|
||||
* Copyright (C) 2019 - 2022 Jonas Lochmann
|
||||
* 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
|
||||
@@ -24,6 +24,7 @@ import { ForceSyncAction, SerializedForceSyncAction } from '../forcesync'
|
||||
import { ReplyToKeyRequestAction, SerializedReplyToKeyRequestAction } from '../replytokeyrequest'
|
||||
import { MarkTaskPendingAction, SerializedMarkTaskPendingAction } from '../marktaskpendingaction'
|
||||
import { UnknownActionTypeException } from '../meta/exception'
|
||||
import { PingAction, SerializedPingAction } from '../ping'
|
||||
import { UpdateInstalledAppsAction, SerializedUpdateInstalledAppsAction } from '../updateinstalledapps'
|
||||
import { RemoveInstalledAppsAction, SerializedRemoveInstalledAppsAction } from '../removeinstalledapps'
|
||||
import { SendKeyRequestAction, SerializedSendKeyRequestAction } from '../sendkeyrequest'
|
||||
@@ -41,6 +42,7 @@ export type SerializedAppLogicAction =
|
||||
SerializedForceSyncAction |
|
||||
SerializedReplyToKeyRequestAction |
|
||||
SerializedMarkTaskPendingAction |
|
||||
SerializedPingAction |
|
||||
SerializedUpdateInstalledAppsAction |
|
||||
SerializedRemoveInstalledAppsAction |
|
||||
SerializedSendKeyRequestAction |
|
||||
@@ -65,6 +67,8 @@ export const parseAppLogicAction = (serialized: SerializedAppLogicAction): AppLo
|
||||
return ReplyToKeyRequestAction.parse(serialized)
|
||||
} else if (serialized.type === 'MARK_TASK_PENDING') {
|
||||
return MarkTaskPendingAction.parse(serialized)
|
||||
} else if (serialized.type === 'PING') {
|
||||
return PingAction.parse(serialized)
|
||||
} else if (serialized.type === 'UPDATE_INSTALLED_APPS') {
|
||||
return UpdateInstalledAppsAction.parse(serialized)
|
||||
} else if (serialized.type === 'REMOVE_INSTALLED_APPS') {
|
||||
|
||||
@@ -1759,6 +1759,41 @@ const definitions = {
|
||||
"type"
|
||||
]
|
||||
},
|
||||
"SerializedPingAction": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"PING"
|
||||
]
|
||||
},
|
||||
"deviceId": {
|
||||
"type": "string"
|
||||
},
|
||||
"event": {
|
||||
"$ref": "#/definitions/PingEvent"
|
||||
},
|
||||
"token": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"deviceId",
|
||||
"event",
|
||||
"token",
|
||||
"type"
|
||||
]
|
||||
},
|
||||
"PingEvent": {
|
||||
"enum": [
|
||||
"clear",
|
||||
"ping",
|
||||
"pong"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"SerializedUpdateInstalledAppsAction": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -2815,6 +2850,30 @@ const definitions = {
|
||||
"tempKey"
|
||||
]
|
||||
},
|
||||
"ServerPing": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"deviceId": {
|
||||
"type": "string"
|
||||
},
|
||||
"token": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"enum": [
|
||||
"ping",
|
||||
"pong"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"deviceId",
|
||||
"token",
|
||||
"type"
|
||||
]
|
||||
},
|
||||
"ServerDhKey": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -3213,6 +3272,9 @@ export const isSerializedAppLogicAction: (value: unknown) => value is Serialized
|
||||
{
|
||||
"$ref": "#/definitions/SerializedMarkTaskPendingAction"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/SerializedPingAction"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/SerializedUpdateInstalledAppsAction"
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* server component for the TimeLimit App
|
||||
* Copyright (C) 2019 - 2022 Jonas Lochmann
|
||||
* 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
|
||||
@@ -33,6 +33,7 @@ import { createKeyResponseModel, KeyResponseModelStatic } from './keyresponse'
|
||||
import { createMailLoginTokenModel, MailLoginTokenModelStatic } from './maillogintoken'
|
||||
import { createUmzug } from './migration/umzug'
|
||||
import { createOldDeviceModel, OldDeviceModelStatic } from './olddevice'
|
||||
import { createPingModel, PingModelStatic } from './ping'
|
||||
import { createPurchaseModel, PurchaseModelStatic } from './purchase'
|
||||
import { createSessionDurationModel, SessionDurationModelStatic } from './sessionduration'
|
||||
import { createTimelimitRuleModel, TimelimitRuleModelStatic } from './timelimitrule'
|
||||
@@ -61,6 +62,7 @@ export interface Database {
|
||||
keyResponse: KeyResponseModelStatic
|
||||
mailLoginToken: MailLoginTokenModelStatic
|
||||
oldDevice: OldDeviceModelStatic
|
||||
ping: PingModelStatic
|
||||
purchase: PurchaseModelStatic
|
||||
sessionDuration: SessionDurationModelStatic
|
||||
timelimitRule: TimelimitRuleModelStatic
|
||||
@@ -97,6 +99,7 @@ const createDatabase = (sequelize: Sequelize.Sequelize): Database => ({
|
||||
keyResponse: createKeyResponseModel(sequelize),
|
||||
mailLoginToken: createMailLoginTokenModel(sequelize),
|
||||
oldDevice: createOldDeviceModel(sequelize),
|
||||
ping: createPingModel(sequelize),
|
||||
purchase: createPurchaseModel(sequelize),
|
||||
sessionDuration: createSessionDurationModel(sequelize),
|
||||
timelimitRule: createTimelimitRuleModel(sequelize),
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { QueryInterface, Sequelize, Transaction } from 'sequelize'
|
||||
|
||||
export async function up (queryInterface: QueryInterface, sequelize: Sequelize) {
|
||||
await sequelize.transaction({
|
||||
type: Transaction.TYPES.EXCLUSIVE
|
||||
}, async (transaction) => {
|
||||
const dialect = sequelize.getDialect()
|
||||
const isMysql = dialect === 'mysql' || dialect === 'mariadb'
|
||||
|
||||
if (isMysql) {
|
||||
await sequelize.query(
|
||||
'CREATE TABLE `Pings` ' +
|
||||
'(`familyId` VARCHAR(10) NOT NULL,' +
|
||||
'`receiverDeviceId` VARCHAR(6) NOT NULL,' +
|
||||
'`senderDeviceId` VARCHAR(6) NOT NULL,' +
|
||||
'`type` INTEGER NOT NULL,' +
|
||||
'`token` VARCHAR(6) NOT NULL,' +
|
||||
'PRIMARY KEY (`familyId`, `receiverDeviceId`, `senderDeviceId`, `type`),' +
|
||||
'FOREIGN KEY (`familyId`, `receiverDeviceId`) REFERENCES `Devices` (`familyId`, `deviceId`) ON UPDATE CASCADE ON DELETE CASCADE,' +
|
||||
'FOREIGN KEY (`familyId`, `senderDeviceId`) REFERENCES `Devices` (`familyId`, `deviceId`) ON UPDATE CASCADE ON DELETE CASCADE' +
|
||||
')',
|
||||
{ transaction }
|
||||
)
|
||||
} else {
|
||||
await sequelize.query(
|
||||
'CREATE TABLE "Pings" ' +
|
||||
'("familyId" VARCHAR(10) NOT NULL,' +
|
||||
'"receiverDeviceId" VARCHAR(6) NOT NULL,' +
|
||||
'"senderDeviceId" VARCHAR(6) NOT NULL,' +
|
||||
'"type" INTEGER NOT NULL,' +
|
||||
'"token" VARCHAR(6) NOT NULL,' +
|
||||
'PRIMARY KEY ("familyId", "receiverDeviceId", "senderDeviceId", "type"),' +
|
||||
'FOREIGN KEY ("familyId", "receiverDeviceId") REFERENCES "Devices" ("familyId", "deviceId") ON UPDATE CASCADE ON DELETE CASCADE,' +
|
||||
'FOREIGN KEY ("familyId", "senderDeviceId") REFERENCES "Devices" ("familyId", "deviceId") ON UPDATE CASCADE ON DELETE CASCADE' +
|
||||
')',
|
||||
{ transaction }
|
||||
)
|
||||
}
|
||||
|
||||
await queryInterface.addIndex('Pings', ['familyId', 'senderDeviceId'], { transaction })
|
||||
})
|
||||
}
|
||||
|
||||
export async function down (queryInterface: QueryInterface, sequelize: Sequelize) {
|
||||
await sequelize.transaction({
|
||||
type: Transaction.TYPES.EXCLUSIVE
|
||||
}, async (transaction) => {
|
||||
await queryInterface.dropTable('Pings', { transaction })
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import * as Sequelize from 'sequelize'
|
||||
import { familyIdColumn, idWithinFamilyColumn } from './columns'
|
||||
import { SequelizeAttributes } from './types'
|
||||
|
||||
export interface PingAttributes {
|
||||
familyId: string
|
||||
receiverDeviceId: string
|
||||
senderDeviceId: string
|
||||
type: number
|
||||
token: string
|
||||
}
|
||||
|
||||
export const types = {
|
||||
ping: 1,
|
||||
pong: 2,
|
||||
all: [1, 2]
|
||||
}
|
||||
|
||||
export type PingModel = Sequelize.Model<PingAttributes> & PingAttributes
|
||||
export type PingModelStatic = typeof Sequelize.Model & {
|
||||
new (values?: object, options?: Sequelize.BuildOptions): PingModel;
|
||||
}
|
||||
|
||||
export const attributes: SequelizeAttributes<PingAttributes> = {
|
||||
familyId: {
|
||||
...familyIdColumn,
|
||||
primaryKey: true
|
||||
},
|
||||
receiverDeviceId: {
|
||||
...idWithinFamilyColumn,
|
||||
primaryKey: true
|
||||
},
|
||||
senderDeviceId: {
|
||||
...idWithinFamilyColumn,
|
||||
primaryKey: true
|
||||
},
|
||||
type: {
|
||||
type: Sequelize.INTEGER,
|
||||
allowNull: false,
|
||||
validate: {
|
||||
isIn: [types.all]
|
||||
},
|
||||
primaryKey: true
|
||||
},
|
||||
token: {
|
||||
...idWithinFamilyColumn
|
||||
}
|
||||
}
|
||||
|
||||
export const createPingModel = (sequelize: Sequelize.Sequelize): PingModelStatic => sequelize.define('Ping', attributes) as PingModelStatic
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* server component for the TimeLimit App
|
||||
* Copyright (C) 2019 - 2022 Jonas Lochmann
|
||||
* 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
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
FinishKeyRequestAction,
|
||||
ForceSyncAction,
|
||||
MarkTaskPendingAction,
|
||||
PingAction,
|
||||
ReplyToKeyRequestAction,
|
||||
RemoveInstalledAppsAction,
|
||||
SendKeyRequestAction,
|
||||
@@ -41,6 +42,7 @@ import { dispatchAddUsedTimeVersion2 } from './addusedtime2'
|
||||
import { dispatchFinishKeyRequestAction } from './finishkeyrequest'
|
||||
import { dispatchForceSyncAction } from './forcesync'
|
||||
import { dispatchMarkTaskPendingAction } from './marktaskpendingaction'
|
||||
import { dispatchPingAction } from './ping'
|
||||
import { dispatchReplyToKeyRequestAction } from './replytokeyrequest'
|
||||
import { dispatchSendKeyRequestAction } from './sendkeyrequest'
|
||||
import { dispatchSignOutAtDevice } from './signoutatdevice'
|
||||
@@ -67,6 +69,8 @@ export const dispatchAppLogicAction = async ({ action, deviceId, cache, eventHan
|
||||
await dispatchForceSyncAction({ deviceId, action, cache })
|
||||
} else if (action instanceof MarkTaskPendingAction) {
|
||||
await dispatchMarkTaskPendingAction({ deviceId, action, cache })
|
||||
} else if (action instanceof PingAction) {
|
||||
await dispatchPingAction({ deviceId, action, cache })
|
||||
} else if (action instanceof ReplyToKeyRequestAction) {
|
||||
await dispatchReplyToKeyRequestAction({ deviceId, action, cache, eventHandler })
|
||||
} else if (action instanceof RemoveInstalledAppsAction) {
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { PingAction } from '../../../../action'
|
||||
import { types as pingTypes } from '../../../../database/ping'
|
||||
import { Cache } from '../cache'
|
||||
|
||||
export async function dispatchPingAction ({ action, cache, deviceId }: {
|
||||
deviceId: string
|
||||
action: PingAction
|
||||
cache: Cache
|
||||
}) {
|
||||
// handle insertion
|
||||
if (action.event === 'ping' || action.event === 'pong') {
|
||||
let type
|
||||
|
||||
if (action.event === 'ping') type = pingTypes.ping
|
||||
else if (action.event === 'pong') type = pingTypes.pong
|
||||
else throw new Error()
|
||||
|
||||
// delete any previous ping/pong
|
||||
await cache.database.ping.destroy({
|
||||
where: {
|
||||
familyId: cache.familyId,
|
||||
receiverDeviceId: action.deviceId,
|
||||
senderDeviceId: deviceId,
|
||||
type: type
|
||||
},
|
||||
transaction: cache.transaction
|
||||
})
|
||||
|
||||
// insert
|
||||
await cache.database.ping.create({
|
||||
familyId: cache.familyId,
|
||||
receiverDeviceId: action.deviceId,
|
||||
senderDeviceId: deviceId,
|
||||
type,
|
||||
token: action.token
|
||||
}, {
|
||||
transaction: cache.transaction
|
||||
})
|
||||
|
||||
// notify
|
||||
cache.incrementTargetedTriggeredSyncLevel(action.deviceId, 2)
|
||||
}
|
||||
|
||||
// handle deleting
|
||||
if (action.event === 'pong' || action.event === 'clear') {
|
||||
await cache.database.ping.destroy({
|
||||
where: {
|
||||
familyId: cache.familyId,
|
||||
receiverDeviceId: deviceId,
|
||||
senderDeviceId: action.deviceId,
|
||||
token: action.token
|
||||
},
|
||||
transaction: cache.transaction
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* server component for the TimeLimit App
|
||||
* Copyright (C) 2019 - 2024 Jonas Lochmann
|
||||
* 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
|
||||
@@ -30,6 +30,7 @@ import { getDeviceDetailList } from './device-detail'
|
||||
import { getDeviceList } from './device-list'
|
||||
import { getDeviceDhKeys } from './dh-keys'
|
||||
import { getFamilyEntry } from './family-entry'
|
||||
import { getPings } from './pings'
|
||||
import { getUserList } from './user-list'
|
||||
import { getKeyRequests } from './key-requests'
|
||||
import { getKeyResponses } from './key-responses'
|
||||
@@ -52,13 +53,14 @@ export const generateServerDataStatus = async ({
|
||||
const doesClientSupportCryptoApps = clientLevel >= 4
|
||||
const doesClientSupportDh = clientLevel >= 5
|
||||
const doesClientSupportU2f = clientLevel >= 6
|
||||
const doesClientSupportPing = clientLevel >= 7
|
||||
|
||||
const result: ServerDataStatus = {
|
||||
fullVersion: config.alwaysPro ? 1 : (
|
||||
familyEntry.hasFullVersion ? parseInt(familyEntry.fullVersionUntil, 10) : 0
|
||||
),
|
||||
message: await getStatusMessage({ database, transaction }) || undefined,
|
||||
apiLevel: 8
|
||||
apiLevel: 9
|
||||
}
|
||||
|
||||
if (familyEntry.deviceListVersion !== clientStatus.devices) {
|
||||
@@ -160,5 +162,14 @@ export const generateServerDataStatus = async ({
|
||||
}) || undefined
|
||||
}
|
||||
|
||||
if (doesClientSupportPing) {
|
||||
result.pings = await getPings({
|
||||
database,
|
||||
transaction,
|
||||
familyEntry,
|
||||
deviceId
|
||||
})
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import * as Sequelize from 'sequelize'
|
||||
import { Database } from '../../../database'
|
||||
import { types as pingTypes } from '../../../database/ping'
|
||||
import { ServerPing } from '../../../object/serverdatastatus'
|
||||
import { FamilyEntry } from './family-entry'
|
||||
|
||||
export async function getPings ({
|
||||
database, transaction, familyEntry, deviceId
|
||||
}: {
|
||||
database: Database
|
||||
transaction: Sequelize.Transaction
|
||||
familyEntry: FamilyEntry
|
||||
deviceId: string
|
||||
}): Promise<Array<ServerPing>> {
|
||||
const savedData = await database.ping.findAll({
|
||||
where: {
|
||||
familyId: familyEntry.familyId,
|
||||
receiverDeviceId: deviceId,
|
||||
},
|
||||
attributes: ['senderDeviceId', 'type', 'token'],
|
||||
transaction
|
||||
})
|
||||
|
||||
return savedData.map((row) => ({
|
||||
deviceId: row.senderDeviceId,
|
||||
type: convertType(row.type),
|
||||
token: row.token
|
||||
}))
|
||||
}
|
||||
|
||||
function convertType(type: number): 'ping' | 'pong' {
|
||||
if (type === pingTypes.ping) return 'ping'
|
||||
else if (type === pingTypes.pong) return 'pong'
|
||||
else throw new Error()
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* server component for the TimeLimit App
|
||||
* Copyright (C) 2019 - 2022 Jonas Lochmann
|
||||
* 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
|
||||
@@ -34,6 +34,7 @@ export interface ServerDataStatus {
|
||||
users?: ServerUserList // newUserList
|
||||
krq?: Array<ServerKeyRequest> // pendingKeyRequests
|
||||
kr?: Array<ServerKeyResponse> // keyResponses
|
||||
pings?: Array<ServerPing>
|
||||
dh?: ServerDhKey // Diffie Hellman
|
||||
u2f?: U2fData
|
||||
fullVersion: number // fullVersionUntil
|
||||
@@ -257,6 +258,12 @@ export interface ServerKeyResponse {
|
||||
signature: string
|
||||
}
|
||||
|
||||
export interface ServerPing {
|
||||
deviceId: string
|
||||
token: string
|
||||
type: 'ping' | 'pong'
|
||||
}
|
||||
|
||||
export interface ServerDhKey {
|
||||
v: string // version
|
||||
k: string // key, base64
|
||||
|
||||
Reference in New Issue
Block a user