Make websocket pushes more targeted

This commit is contained in:
Jonas Lochmann 2022-09-19 02:00:00 +02:00
parent 613776cbf9
commit 84f6f0df69
No known key found for this signature in database
GPG key ID: 8B8C9AEE10FA5B36
78 changed files with 224 additions and 140 deletions

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -65,7 +65,15 @@ export const addChildDevice = async ({ database, websocket, request }: {
transaction
})
await notifyClientsAboutChangesDelayed({ familyId, websocket, database, isImportant: true, sourceDeviceId: deviceId, transaction })
await notifyClientsAboutChangesDelayed({
familyId,
websocket,
database,
generalLevel: 1,
targetedLevels: new Map(),
sourceDeviceId: deviceId,
transaction
})
return {
deviceId,

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2021 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -164,7 +164,8 @@ export const setPrimaryDevice = async ({ database, websocket, deviceAuthToken, c
sourceDeviceId: deviceEntry.deviceId,
websocket,
database,
isImportant: false, // the source device knows it already
generalLevel: 1, // the source device knows it already
targetedLevels: new Map(),
transaction
})

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -104,7 +104,8 @@ export async function removeDevice ({ database, familyId, deviceId, websocket, t
websocket,
familyId,
sourceDeviceId: null,
isImportant: false,
generalLevel: 1,
targetedLevels: new Map(),
transaction
})

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -65,7 +65,8 @@ export async function reportDeviceRemoved ({ database, deviceAuthToken, websocke
websocket,
familyId: deviceEntry.familyId,
sourceDeviceId: null,
isImportant: false,
generalLevel: 1,
targetedLevels: new Map(),
transaction
})

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2021 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -101,9 +101,10 @@ export const linkMailAddress = async ({ mailAuthToken, deviceAuthToken, parentUs
await notifyClientsAboutChangesDelayed({
familyId,
sourceDeviceId: null,
generalLevel: 1,
targetedLevels: new Map(),
database,
websocket,
isImportant: true,
transaction
})
})

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2021 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -68,7 +68,8 @@ export const recoverParentPassword = async ({ database, websocket, password, mai
database,
familyId: userEntry.familyId,
websocket,
isImportant: true,
generalLevel: 2,
targetedLevels: new Map(),
sourceDeviceId: null,
transaction
})

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2021 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -80,7 +80,8 @@ export const signInIntoFamily = async ({ database, mailAuthToken, newDeviceInfo,
familyId: userEntry.familyId,
websocket,
database,
isImportant: true,
generalLevel: 1,
targetedLevels: new Map(),
sourceDeviceId: deviceId,
transaction
})

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2021 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -83,7 +83,8 @@ export const addPurchase = async ({ database, familyId, type, transactionId, web
sourceDeviceId: null,
database,
websocket,
isImportant: true,
generalLevel: 2,
targetedLevels: new Map(),
transaction
})
}

View file

@ -32,7 +32,7 @@ export class Cache {
transaction: Sequelize.Transaction
readonly database: Database
readonly connectedDevicesManager: VisibleConnectedDevicesManager
private shouldTriggerFullSync = false
private requireSenderDoFullSync = false
categoriesWithModifiedApps = new Set<string>()
categoriesWithModifiedBaseData = new Set<string>()
@ -46,7 +46,8 @@ export class Cache {
invalidiateUserList = false
invalidiateDeviceList = false
invalidateU2fList = false
areChangesImportant = false
triggeredSyncLevel: 0 | 1 | 2 = 0 // 0 = no, 1 = unimportant, 2 = important
targetedTriggeredSyncLevels = new Map<string, 0 | 1 | 2>()
constructor ({ familyId, deviceId, hasFullVersion, database, transaction, connectedDevicesManager }: {
familyId: string
@ -64,6 +65,16 @@ export class Cache {
this.connectedDevicesManager = connectedDevicesManager
}
incrementTriggeredSyncLevel(newLevel: 1 | 2) {
if (newLevel > this.triggeredSyncLevel) this.triggeredSyncLevel = newLevel
}
incrementTargetedTriggeredSyncLevel(deviceId: string, newLevel: 1 | 2) {
const oldLevel = this.targetedTriggeredSyncLevels.get(deviceId) || 0
if (newLevel > oldLevel) this.targetedTriggeredSyncLevels.set(deviceId, newLevel)
}
async subtransaction<T> (callback: () => Promise<T>): Promise<T> {
const oldTransaction = this.transaction
@ -144,8 +155,8 @@ export class Cache {
return !!userEntry
})
shouldDoFullSync = () => this.shouldTriggerFullSync
requireFullSync: () => void = () => this.shouldTriggerFullSync = true
isSenderDoFullSyncTrue = () => this.requireSenderDoFullSync
requireSenderFullSync: () => void = () => this.requireSenderDoFullSync = true
async saveModifiedVersionNumbers () {
const { database, transaction, familyId } = this

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -59,4 +59,5 @@ export async function dispatchAddInstalledApps ({ deviceId, action, cache }: {
)
cache.devicesWithModifiedInstalledApps.add(deviceId)
cache.incrementTriggeredSyncLevel(1)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2021 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -156,4 +156,6 @@ export async function dispatchAddUsedTime ({ action, cache }: {
})
}
}
cache.incrementTriggeredSyncLevel(1)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2021 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -72,7 +72,7 @@ export async function dispatchAddUsedTimeVersion2 ({ deviceId, action, cache, ev
// verify that the category exists
if (!categoryEntryUnsafe) {
eventHandler.countEvent('add used time category to add time for not found')
cache.requireFullSync()
cache.requireSenderFullSync()
continue
}
@ -247,9 +247,11 @@ export async function dispatchAddUsedTimeVersion2 ({ deviceId, action, cache, ev
// As it should occur not too often, a full sync should be no problem.
// To keep an eye on it, it is counted.
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
eventHandler.countEvent('add used time for a different user than the current user of the device')
}
}
cache.incrementTriggeredSyncLevel(1)
}

View file

@ -31,4 +31,6 @@ export async function dispatchFinishKeyRequestAction ({ action, cache, deviceId
},
transaction: cache.transaction
})
// no sync triggered
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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,5 +23,5 @@ export async function dispatchForceSyncAction ({ cache }: {
action: ForceSyncAction
cache: Cache
}) {
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -99,6 +99,7 @@ export async function dispatchMarkTaskPendingAction ({ action, cache, deviceId }
})
cache.categoriesWithModifiedTasks.add(taskInfo.categoryId)
cache.incrementTriggeredSyncLevel(1) // parents are not faster reachable
await sendTaskDoneMails({
database: cache.database,

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -36,4 +36,5 @@ export async function dispatchRemoveInstalledApps ({ deviceId, action, cache }:
})
cache.devicesWithModifiedInstalledApps.add(deviceId)
cache.incrementTriggeredSyncLevel(1)
}

View file

@ -105,6 +105,5 @@ export async function dispatchReplyToKeyRequestAction ({ deviceId, action, cache
transaction: cache.transaction
})
// there is no way (yet) to inform the specific device only
cache.areChangesImportant = true
cache.incrementTargetedTriggeredSyncLevel(request.senderDeviceId, 2)
}

View file

@ -72,5 +72,5 @@ export async function dispatchSendKeyRequestAction ({ action, cache, deviceId }:
transaction: cache.transaction
})
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -57,4 +57,6 @@ export async function dispatchSignOutAtDevice ({ deviceId, cache }: {
})
})
}
cache.incrementTriggeredSyncLevel(1)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -46,7 +46,7 @@ export async function dispatchTriedDisablingDeviceAdmin ({ deviceId, cache }: {
await deviceEntry.save({ transaction: cache.transaction })
cache.invalidiateDeviceList = true
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(1)
}
if (!hadManipulationBefore) {

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -95,4 +95,5 @@ export async function dispatchUpdateAppActivities ({ deviceId, action, cache }:
}
cache.devicesWithModifiedInstalledApps.add(deviceId)
cache.incrementTriggeredSyncLevel(1)
}

View file

@ -177,5 +177,5 @@ export async function dispatchUpdateDeviceStatus ({ deviceId, action, cache }: {
}
cache.invalidiateDeviceList = true
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(1)
}

View file

@ -54,4 +54,6 @@ export async function dispatchUpdateInstalledApps ({ deviceId, action, cache }:
cache.devicesWithModifiedInstalledApps.add(deviceId)
}
cache.incrementTriggeredSyncLevel(1)
}

View file

@ -42,6 +42,7 @@ export async function dispatchUploadDevicePublicKeyAction ({ deviceId, action, c
await deviceEntry.save({ transaction: cache.transaction })
cache.invalidiateDeviceList = true
cache.incrementTriggeredSyncLevel(2)
} else if (deviceEntry.publicKey.equals(action.key)) {
eventHandler.countEvent('dispatchUploadDevicePublicKeyAction:duplicate action')
} else {

View file

@ -52,5 +52,5 @@ export const dispatchChildChangePassword = async ({ action, childUserId, cache }
}
cache.invalidiateUserList = true
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -71,4 +71,6 @@ export const dispatchChildSignIn = async ({ deviceId, childUserId, cache }: {
cache.invalidiateUserList = true
}
cache.incrementTriggeredSyncLevel(1)
}

View file

@ -189,5 +189,5 @@ export async function dispatchAddCategoryApps ({ action, cache, fromChildSelfLim
oldCategories.forEach((categoryId) => cache.categoriesWithModifiedApps.add(categoryId))
cache.categoriesWithModifiedApps.add(action.categoryId)
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -75,5 +75,5 @@ export async function dispatchAddCategoryNetworkId ({ action, cache }: {
}, { transaction: cache.transaction })
cache.categoriesWithModifiedBaseData.add(action.categoryId)
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
}

View file

@ -52,5 +52,5 @@ export async function dispatchAddU2f ({ action, cache, parentUserId, authenticat
}, { transaction: cache.transaction })
cache.invalidateU2fList = true
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(1)
}

View file

@ -48,7 +48,7 @@ export async function dispatchAddUser ({ action, cache }: {
}, { transaction: cache.transaction })
cache.invalidiateUserList = true
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(1)
cache.doesUserExist.cache.set(action.userId, true)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2021 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -59,5 +59,5 @@ export async function dispatchChangeParentPassword ({ action, cache }: {
}
cache.invalidiateUserList = true
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2021 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -86,5 +86,5 @@ export async function dispatchCreateCategory ({ action, cache, fromChildSelfLimi
// update the cache
cache.doesCategoryExist.cache.set(action.categoryId, true)
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(1)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -59,5 +59,5 @@ export async function dispatchCreateTimeLimitRule ({ action, cache, fromChildSel
}, { transaction: cache.transaction })
cache.categoriesWithModifiedTimeLimitRules.add(action.rule.categoryId)
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -80,7 +80,7 @@ export async function dispatchDeleteCategory ({ action, cache }: {
// update the cache
cache.doesCategoryExist.cache.set(action.categoryId, false)
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
if (affectedUserRows !== 0) {
cache.invalidiateUserList = true

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -45,4 +45,5 @@ export async function dispatchDeleteChildTaskAction ({ action, cache }: {
})
cache.categoriesWithModifiedTasks.add(taskInfo.categoryId)
cache.incrementTriggeredSyncLevel(1)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -38,5 +38,5 @@ export async function dispatchDeleteTimeLimitRule ({ action, cache }: {
await ruleEntry.destroy({ transaction: cache.transaction })
cache.categoriesWithModifiedTimeLimitRules.add(ruleEntry.categoryId)
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
}

View file

@ -87,4 +87,6 @@ export async function dispatchIgnoreManipulation ({ action, cache }: {
await deviceEntry.save({ transaction: cache.transaction })
cache.invalidiateDeviceList = true
cache.incrementTriggeredSyncLevel(1)
cache.incrementTargetedTriggeredSyncLevel(action.deviceId, 2)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -41,7 +41,7 @@ export async function dispatchIncrementCategoryExtraTime ({ action, cache }: {
await category.save({ transaction: cache.transaction })
cache.categoriesWithModifiedBaseData.add(category.categoryId)
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
}
const categoryEntry = await cache.database.category.findOne({

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -42,5 +42,5 @@ export async function dispatchRemoveCategoryApps ({ action, cache }: {
}
cache.categoriesWithModifiedApps.add(action.categoryId)
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
}

View file

@ -43,5 +43,5 @@ export async function dispatchRemoveU2f ({ action, cache, parentUserId, authenti
})
cache.invalidateU2fList = true
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2021 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -178,7 +178,7 @@ export async function dispatchRemoveUser ({ action, cache, parentUserId }: {
await user.destroy({ transaction: cache.transaction })
cache.invalidiateUserList = true
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
cache.doesUserExist.cache.set(action.userId, false)
cache.getSecondPasswordHashOfParent.cache.delete(action.userId)

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -49,4 +49,5 @@ export async function dispatchRenameChild ({ action, cache }: {
cache.invalidiateUserList = true
cache.doesUserExist.cache.set(action.childId, false)
cache.incrementTriggeredSyncLevel(1)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -45,5 +45,5 @@ export async function dispatchResetCategoryNetworkIds ({ action, cache }: {
})
cache.categoriesWithModifiedBaseData.add(action.categoryId)
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
}

View file

@ -98,6 +98,8 @@ export async function dispatchReviewChildTaskAction ({ action, cache }: {
},
transaction: cache.transaction
})
cache.incrementTriggeredSyncLevel(2)
} else {
await cache.database.childTask.update({
pendingRequest: 0
@ -111,4 +113,5 @@ export async function dispatchReviewChildTaskAction ({ action, cache }: {
}
cache.categoriesWithModifiedTasks.add(taskInfo.categoryId)
cache.incrementTriggeredSyncLevel(1)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -52,5 +52,5 @@ export async function dispatchSetCategoryExtraTime ({ action, cache }: {
})
cache.categoriesWithModifiedBaseData.add(action.categoryId)
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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,5 +78,5 @@ export async function dispatchSetCategoryForUnassignedApps ({ action, cache }: {
})
cache.invalidiateUserList = true
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
}

View file

@ -51,5 +51,5 @@ export async function dispatchSetChildPassword ({ action, cache }: {
}
cache.invalidiateUserList = true
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -46,5 +46,7 @@ export async function dispatchSetConsiderRebootManipulation ({ action, cache }:
})
cache.invalidiateDeviceList = true
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(1)
cache.incrementTargetedTriggeredSyncLevel(action.deviceId, 2)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -54,5 +54,7 @@ export async function dispatchSetDeviceDefaultUser ({ action, cache }: {
})
cache.invalidiateDeviceList = true
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(1)
cache.incrementTargetedTriggeredSyncLevel(action.deviceId, 2)
}

View file

@ -46,5 +46,7 @@ export async function dispatchSetDeviceDefaultUserTimeout ({ action, cache }: {
})
cache.invalidiateDeviceList = true
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(1)
cache.incrementTargetedTriggeredSyncLevel(action.deviceId, 2)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -55,5 +55,7 @@ export async function dispatchSetDeviceUser ({ action, cache }: {
})
cache.invalidiateDeviceList = true
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(1)
cache.incrementTargetedTriggeredSyncLevel(action.deviceId, 2)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -63,6 +63,8 @@ export async function dispatchSetKeepSignedIn ({ action, cache, parentUserId }:
if (affectedRows !== 0) {
cache.invalidiateDeviceList = true
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(1)
cache.incrementTargetedTriggeredSyncLevel(action.deviceId, 2)
}
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -118,5 +118,5 @@ export async function dispatchSetParentCategory ({ action, cache, fromChildSelfL
})
cache.categoriesWithModifiedBaseData.add(action.categoryId)
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -48,5 +48,5 @@ export async function dispatchSetRelaxPrimaryDevice ({ action, cache }: {
})
cache.invalidiateUserList = true
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -42,4 +42,6 @@ export async function dispatchSetSendDeviceConnected ({ action, cache, sourceDev
cache.devicesWithModifiedShowDeviceConnected.set(action.deviceId, action.enable)
cache.invalidiateDeviceList = true
cache.incrementTriggeredSyncLevel(1)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -55,5 +55,5 @@ export async function dispatchUserSetDisableLimitsUntil ({ action, cache }: {
})
cache.invalidiateUserList = true
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -46,5 +46,5 @@ export async function dispatchSetUserTimezone ({ action, cache }: {
})
cache.invalidiateUserList = true
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -46,5 +46,5 @@ export async function dispatchUpdateCategoryBatteryLimit ({ action, cache }: {
await categoryEntry.save({ transaction: cache.transaction })
cache.categoriesWithModifiedBaseData.add(action.categoryId)
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2021 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -72,6 +72,6 @@ export async function dispatchUpdateCategoryBlockAllNotifications ({ action, cac
if (affectedRows !== 0) {
cache.categoriesWithModifiedBaseData.add(action.categoryId)
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
}
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -70,5 +70,5 @@ export async function dispatchUpdateCategoryBlockedTimes ({ action, cache, fromC
})
cache.categoriesWithModifiedBaseData.add(action.categoryId)
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -71,6 +71,6 @@ export async function dispatchUpdateCategoryDisableLimits ({ action, cache, from
if (affectedRows !== 0) {
cache.categoriesWithModifiedBaseData.add(action.categoryId)
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
}
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2021 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -49,4 +49,5 @@ export async function dispatchUpdateCategoryFlagsAction ({ action, cache }: {
await categoryEntry.save({ transaction: cache.transaction })
cache.categoriesWithModifiedBaseData.add(action.categoryId)
cache.incrementTriggeredSyncLevel(2)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -42,4 +42,6 @@ export async function dispatchUpdateCategorySorting ({ action, cache }: {
cache.categoriesWithModifiedBaseData.add(categoryId)
}
cache.incrementTriggeredSyncLevel(1)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -80,6 +80,6 @@ export async function dispatchUpdateCategoryTemporarilyBlocked ({ action, cache,
if (affectedRows !== 0) {
cache.categoriesWithModifiedBaseData.add(action.categoryId)
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
}
}

View file

@ -66,5 +66,5 @@ export async function dispatchUpdateCategoryTimeWarnings ({ action, cache }: {
}
cache.categoriesWithModifiedBaseData.add(action.categoryId)
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -47,6 +47,6 @@ export async function dispatchUpdateCategoryTitle ({ action, cache }: {
if (affectedRows !== 0) {
cache.categoriesWithModifiedBaseData.add(action.categoryId)
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
}
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -84,5 +84,6 @@ export async function dispatchUpdateChildTaskAction ({ action, cache }: {
cache.categoriesWithModifiedTasks.add(taskInfo.categoryId)
cache.categoriesWithModifiedTasks.add(action.categoryId)
cache.incrementTriggeredSyncLevel(1)
}
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -47,6 +47,6 @@ export async function dispatchUpdateDeviceName ({ action, cache }: {
if (affectedRows !== 0) {
cache.invalidiateDeviceList = true
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(1)
}
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -46,5 +46,6 @@ export async function dispatchUpdateEnableActivityLevelBlocking ({ action, cache
})
cache.invalidiateDeviceList = true
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(1)
cache.incrementTargetedTriggeredSyncLevel(action.deviceId, 2)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -46,5 +46,7 @@ export async function dispatchUpdateNetworkTimeVerification ({ action, cache }:
})
cache.invalidiateDeviceList = true
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(1)
cache.incrementTargetedTriggeredSyncLevel(action.deviceId, 1)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -45,4 +45,5 @@ export async function dispatchUpdateParentNotificationFlags ({ action, cache }:
await parentEntry.save({ transaction: cache.transaction })
cache.invalidiateUserList = true
cache.incrementTriggeredSyncLevel(1)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -47,5 +47,5 @@ export async function dispatchUpdateTimelimitRule ({ action, cache }: {
await ruleEntry.save({ transaction: cache.transaction })
cache.categoriesWithModifiedTimeLimitRules.add(ruleEntry.categoryId)
cache.areChangesImportant = true
cache.incrementTriggeredSyncLevel(2)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -49,4 +49,5 @@ export async function dispatchUpdateUserFlagsAction ({ action, cache }: {
await userEntry.save({ transaction: cache.transaction })
cache.invalidiateUserList = true
cache.incrementTriggeredSyncLevel(1)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -76,4 +76,5 @@ export async function dispatchUpdateUserLimitLoginCategoryAction ({ action, cach
}
cache.invalidiateUserList = true
cache.incrementTriggeredSyncLevel(2)
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -69,4 +69,5 @@ export async function dispatchUpdateUserLimitPreBlockDuration ({ action, cache,
})
cache.invalidiateUserList = true
cache.incrementTriggeredSyncLevel(2)
}

View file

@ -124,7 +124,7 @@ export const applyActionsFromDevice = async ({ database, request, websocket, con
eventHandler.countEvent('applyActionsFromDevice errorDispatchingAction:other:' + stack)
}
cache.requireFullSync()
cache.requireSenderFullSync()
}
}
@ -148,20 +148,25 @@ export const applyActionsFromDevice = async ({ database, request, websocket, con
await notifyClientsAboutChangesDelayed({
familyId: baseInfo.familyId,
sourceDeviceId: baseInfo.deviceId,
isImportant: cache.areChangesImportant,
websocket,
database,
transaction
transaction,
generalLevel: cache.triggeredSyncLevel,
targetedLevels: cache.targetedTriggeredSyncLevels
})
if (cache.areChangesImportant) {
if (cache.triggeredSyncLevel === 2) {
transaction.afterCommit(() => {
eventHandler.countEvent('applyActionsFromDevice areChangesImportant')
})
} else if ([...cache.targetedTriggeredSyncLevels.entries()].some((entry) => entry[1] === 2)) {
transaction.afterCommit(() => {
eventHandler.countEvent('applyActionsFromDevice areChangesImportantTargeted')
})
}
return {
shouldDoFullSync: cache.shouldDoFullSync()
shouldDoFullSync: cache.isSenderDoFullSyncTrue()
}
})
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2020 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -15,39 +15,45 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import * as Sequelize from 'sequelize'
import { Database, Transaction } from '../../database'
import { WebsocketApi } from '../../websocket'
export const notifyClientsAboutChangesDelayed = async ({ familyId, sourceDeviceId, database, websocket, isImportant, transaction }: {
export const notifyClientsAboutChangesDelayed = async ({
familyId, sourceDeviceId, database,
websocket, transaction, generalLevel, targetedLevels
}: {
familyId: string
sourceDeviceId: string | null // this device will not get an push
database: Database
websocket: WebsocketApi
isImportant: boolean
transaction: Transaction
generalLevel: 0 | 1 | 2
targetedLevels: Map<string, 0 | 1 | 2>
}) => {
const relatedDeviceEntries = (await database.device.findAll({
where: sourceDeviceId ? {
familyId,
deviceId: {
[Sequelize.Op.not]: sourceDeviceId
}
} : {
where: {
familyId
},
attributes: ['deviceAuthToken'],
attributes: ['deviceId', 'deviceAuthToken'],
transaction
})).map((item) => ({
deviceId: item.deviceId,
deviceAuthToken: item.deviceAuthToken
}))
transaction.afterCommit(() => {
relatedDeviceEntries.forEach((item) => {
for (const deviceEntry of relatedDeviceEntries) {
if (deviceEntry.deviceId === sourceDeviceId) continue
const targetedLevel = targetedLevels.get(deviceEntry.deviceId) ?? 0
const effectiveLevel = Math.max(targetedLevel, generalLevel)
if (effectiveLevel > 0) {
websocket.triggerSyncByDeviceAuthToken({
deviceAuthToken: item.deviceAuthToken,
isImportant
})
deviceAuthToken: deviceEntry.deviceAuthToken,
isImportant: effectiveLevel === 2
})
}
}
})
}

View file

@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 - 2021 Jonas Lochmann
* Copyright (C) 2019 - 2022 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
@ -77,7 +77,8 @@ async function deleteDeprecatedPurchases ({ database, websocket }: {
sourceDeviceId: null,
database,
websocket,
isImportant: true,
generalLevel: 2,
targetedLevels: new Map(),
transaction
})
}