Allow blocked time area extension with the self limitation

This commit is contained in:
Jonas Lochmann 2020-08-31 02:00:00 +02:00
parent eb6f668b43
commit a6723430ca
No known key found for this signature in database
GPG key ID: 8B8C9AEE10FA5B36
4 changed files with 46 additions and 13 deletions

View file

@ -1,6 +1,6 @@
/* /*
* server component for the TimeLimit App * server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann * Copyright (C) 2019 - 2020 Jonas Lochmann
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as * it under the terms of the GNU Affero General Public License as
@ -19,6 +19,8 @@ import { validateBitmask } from '../util/bitmask'
import { assertIdWithinFamily } from '../util/token' import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes' import { ParentAction } from './basetypes'
export const blockedTimesBitmaskLength = 60 * 24 * 7 /* number of minutes per week */
export class UpdateCategoryBlockedTimesAction extends ParentAction { export class UpdateCategoryBlockedTimesAction extends ParentAction {
readonly categoryId: string readonly categoryId: string
readonly blockedTimes: string readonly blockedTimes: string
@ -30,7 +32,7 @@ export class UpdateCategoryBlockedTimesAction extends ParentAction {
super() super()
assertIdWithinFamily(categoryId) assertIdWithinFamily(categoryId)
validateBitmask(blockedTimes, 60 * 24 * 7 /* number of minutes per week */) validateBitmask(blockedTimes, blockedTimesBitmaskLength)
this.categoryId = categoryId this.categoryId = categoryId
this.blockedTimes = blockedTimes this.blockedTimes = blockedTimes

View file

@ -125,6 +125,8 @@ export const dispatchParentAction = async ({ action, cache, parentUserId, source
return dispatchSetParentCategory({ action, cache, fromChildSelfLimitAddChildUserId }) return dispatchSetParentCategory({ action, cache, fromChildSelfLimitAddChildUserId })
} else if (action instanceof UpdateCategoryTemporarilyBlockedAction) { } else if (action instanceof UpdateCategoryTemporarilyBlockedAction) {
return dispatchUpdateCategoryTemporarilyBlocked({ action, cache, fromChildSelfLimitAddChildUserId }) return dispatchUpdateCategoryTemporarilyBlocked({ action, cache, fromChildSelfLimitAddChildUserId })
} else if (action instanceof UpdateCategoryBlockedTimesAction) {
return dispatchUpdateCategoryBlockedTimes({ action, cache, fromChildSelfLimitAddChildUserId })
} }
if (fromChildSelfLimitAddChildUserId === null) { if (fromChildSelfLimitAddChildUserId === null) {
@ -164,8 +166,6 @@ export const dispatchParentAction = async ({ action, cache, parentUserId, source
return dispatchSetUserTimezone({ action, cache }) return dispatchSetUserTimezone({ action, cache })
} else if (action instanceof UpdateCategoryBatteryLimitAction) { } else if (action instanceof UpdateCategoryBatteryLimitAction) {
return dispatchUpdateCategoryBatteryLimit({ action, cache }) return dispatchUpdateCategoryBatteryLimit({ action, cache })
} else if (action instanceof UpdateCategoryBlockedTimesAction) {
return dispatchUpdateCategoryBlockedTimes({ action, cache })
} else if (action instanceof UpdateCategorySortingAction) { } else if (action instanceof UpdateCategorySortingAction) {
return dispatchUpdateCategorySorting({ action, cache }) return dispatchUpdateCategorySorting({ action, cache })
} else if (action instanceof IncrementCategoryExtraTimeAction) { } else if (action instanceof IncrementCategoryExtraTimeAction) {

View file

@ -1,6 +1,6 @@
/* /*
* server component for the TimeLimit App * server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann * Copyright (C) 2019 - 2020 Jonas Lochmann
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as * it under the terms of the GNU Affero General Public License as
@ -15,14 +15,49 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import { UpdateCategoryBlockedTimesAction } from '../../../../action' import { blockedTimesBitmaskLength, UpdateCategoryBlockedTimesAction } from '../../../../action/updatecategoryblockedtimes'
import { validateAndParseBitmask } from '../../../../util/bitmask'
import { Cache } from '../cache' import { Cache } from '../cache'
export async function dispatchUpdateCategoryBlockedTimes ({ action, cache }: { export async function dispatchUpdateCategoryBlockedTimes ({ action, cache, fromChildSelfLimitAddChildUserId }: {
action: UpdateCategoryBlockedTimesAction action: UpdateCategoryBlockedTimesAction
cache: Cache cache: Cache
fromChildSelfLimitAddChildUserId: string | null
}) { }) {
const [affectedRows] = await cache.database.category.update({ const categoryEntryUnsafe = await cache.database.category.findOne({
where: {
familyId: cache.familyId,
categoryId: action.categoryId
},
transaction: cache.transaction,
attributes: ['childId', 'blockedMinutesInWeek']
})
if (!categoryEntryUnsafe) {
throw new Error('can not update blocked time areas for a category which does not exist')
}
const categoryEntry = {
childId: categoryEntryUnsafe.childId,
blockedMinutesInWeek: categoryEntryUnsafe.blockedMinutesInWeek
}
if (fromChildSelfLimitAddChildUserId !== null) {
if (categoryEntry.childId !== fromChildSelfLimitAddChildUserId) {
throw new Error('can not update blocked time areas for other child users')
}
const oldBlocked = validateAndParseBitmask(categoryEntry.blockedMinutesInWeek, blockedTimesBitmaskLength)
const newBlocked = validateAndParseBitmask(action.blockedTimes, blockedTimesBitmaskLength)
oldBlocked.forEach((value, index) => {
if (value && !newBlocked[index]) {
throw new Error('new blocked time areas are smaller')
}
})
}
await cache.database.category.update({
blockedMinutesInWeek: action.blockedTimes blockedMinutesInWeek: action.blockedTimes
}, { }, {
where: { where: {
@ -32,10 +67,6 @@ export async function dispatchUpdateCategoryBlockedTimes ({ action, cache }: {
transaction: cache.transaction transaction: cache.transaction
}) })
if (affectedRows === 0) {
throw new Error('invalid category id provided')
}
cache.categoriesWithModifiedBaseData.push(action.categoryId) cache.categoriesWithModifiedBaseData.push(action.categoryId)
cache.areChangesImportant = true cache.areChangesImportant = true
} }

View file

@ -1,6 +1,6 @@
/* /*
* server component for the TimeLimit App * server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann * Copyright (C) 2019 - 2020 Jonas Lochmann
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as * it under the terms of the GNU Affero General Public License as