mirror of
https://codeberg.org/timelimit/timelimit-server.git
synced 2026-08-31 19:03:45 +02:00
Refactor exception usage
This commit is contained in:
@@ -18,8 +18,11 @@
|
||||
import * as Sequelize from 'sequelize'
|
||||
import { AddCategoryAppsAction } from '../../../../action'
|
||||
import { CategoryAppAttributes } from '../../../../database/categoryapp'
|
||||
import { getCategoryWithParentCategories } from '../../../../util/category'
|
||||
import { getCategoryWithParentCategories, GetParentCategoriesException } from '../../../../util/category'
|
||||
import { Cache } from '../cache'
|
||||
import { SourceUserNotFoundException } from '../exception/illegal-state'
|
||||
import { MissingCategoryException } from '../exception/missing-item'
|
||||
import { CanNotModifyOtherUsersBySelfLimitationException, SelfLimitationException } from '../exception/self-limit'
|
||||
|
||||
export async function dispatchAddCategoryApps ({ action, cache, fromChildSelfLimitAddChildUserId }: {
|
||||
action: AddCategoryAppsAction
|
||||
@@ -36,14 +39,14 @@ export async function dispatchAddCategoryApps ({ action, cache, fromChildSelfLim
|
||||
})
|
||||
|
||||
if (!categoryEntryUnsafe) {
|
||||
throw new Error('invalid category id')
|
||||
throw new MissingCategoryException()
|
||||
}
|
||||
|
||||
const { childId } = categoryEntryUnsafe
|
||||
|
||||
if (fromChildSelfLimitAddChildUserId !== null) {
|
||||
if (childId !== fromChildSelfLimitAddChildUserId) {
|
||||
throw new Error('can not add apps to other users')
|
||||
throw new CanNotModifyOtherUsersBySelfLimitationException()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,64 +80,74 @@ export async function dispatchAddCategoryApps ({ action, cache, fromChildSelfLim
|
||||
}).map((item) => item.categoryId)
|
||||
|
||||
if (fromChildSelfLimitAddChildUserId !== null) {
|
||||
const parentCategoriesOfTargetCategory = getCategoryWithParentCategories(categoriesOfSameChild, action.categoryId)
|
||||
const userEntryUnsafe = await cache.database.user.findOne({
|
||||
attributes: [ 'categoryForNotAssignedApps' ],
|
||||
where: {
|
||||
familyId: cache.familyId,
|
||||
userId: fromChildSelfLimitAddChildUserId
|
||||
},
|
||||
transaction: cache.transaction
|
||||
})
|
||||
|
||||
if (!userEntryUnsafe) {
|
||||
throw new Error('illegal state')
|
||||
}
|
||||
|
||||
const userEntry = { categoryForNotAssignedApps: userEntryUnsafe.categoryForNotAssignedApps }
|
||||
const validatedDefaultCategoryId = categoriesOfSameChild.find((item) => item.categoryId === userEntry.categoryForNotAssignedApps)?.categoryId
|
||||
const allowUnassignedElements = validatedDefaultCategoryId !== undefined &&
|
||||
parentCategoriesOfTargetCategory.indexOf(validatedDefaultCategoryId) !== -1
|
||||
|
||||
const assertCanAddApp = async (packageName: string, isApp: boolean) => {
|
||||
const categoryAppEntryUnsafe = await cache.database.categoryApp.findOne({
|
||||
attributes: [ 'categoryId' ],
|
||||
try {
|
||||
const parentCategoriesOfTargetCategory = getCategoryWithParentCategories(categoriesOfSameChild, action.categoryId)
|
||||
const userEntryUnsafe = await cache.database.user.findOne({
|
||||
attributes: [ 'categoryForNotAssignedApps' ],
|
||||
where: {
|
||||
familyId: cache.familyId,
|
||||
categoryId: {
|
||||
[Sequelize.Op.in]: userCategoryIds
|
||||
},
|
||||
packageName: packageName
|
||||
userId: fromChildSelfLimitAddChildUserId
|
||||
},
|
||||
transaction: cache.transaction
|
||||
})
|
||||
|
||||
const categoryAppEntry = categoryAppEntryUnsafe ? { categoryId: categoryAppEntryUnsafe.categoryId } : null
|
||||
if (!userEntryUnsafe) {
|
||||
throw new SourceUserNotFoundException()
|
||||
}
|
||||
|
||||
if (categoryAppEntry === null) {
|
||||
if ((isApp && allowUnassignedElements) || (!isApp)) {
|
||||
// allow
|
||||
const userEntry = { categoryForNotAssignedApps: userEntryUnsafe.categoryForNotAssignedApps }
|
||||
const validatedDefaultCategoryId = categoriesOfSameChild.find((item) => item.categoryId === userEntry.categoryForNotAssignedApps)?.categoryId
|
||||
const allowUnassignedElements = validatedDefaultCategoryId !== undefined &&
|
||||
parentCategoriesOfTargetCategory.indexOf(validatedDefaultCategoryId) !== -1
|
||||
|
||||
const assertCanAddApp = async (packageName: string, isApp: boolean) => {
|
||||
const categoryAppEntryUnsafe = await cache.database.categoryApp.findOne({
|
||||
attributes: [ 'categoryId' ],
|
||||
where: {
|
||||
familyId: cache.familyId,
|
||||
categoryId: {
|
||||
[Sequelize.Op.in]: userCategoryIds
|
||||
},
|
||||
packageName: packageName
|
||||
},
|
||||
transaction: cache.transaction
|
||||
})
|
||||
|
||||
const categoryAppEntry = categoryAppEntryUnsafe ? { categoryId: categoryAppEntryUnsafe.categoryId } : null
|
||||
|
||||
if (categoryAppEntry === null) {
|
||||
if ((isApp && allowUnassignedElements) || (!isApp)) {
|
||||
// allow
|
||||
} else {
|
||||
throw new SelfLimitationException({
|
||||
staticMessage: 'can not assign apps without category as child'
|
||||
})
|
||||
}
|
||||
} else {
|
||||
throw new Error('can not assign apps without category as child')
|
||||
}
|
||||
} else {
|
||||
if (parentCategoriesOfTargetCategory.indexOf(categoryAppEntry.categoryId) !== -1) {
|
||||
// allow
|
||||
} else {
|
||||
throw new Error('can not add app which is not contained in the parent category')
|
||||
if (parentCategoriesOfTargetCategory.indexOf(categoryAppEntry.categoryId) !== -1) {
|
||||
// allow
|
||||
} else {
|
||||
throw new SelfLimitationException({
|
||||
staticMessage: 'can not add app which is not contained in the parent category as child'
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < action.packageNames.length; i++) {
|
||||
const packageName = action.packageNames[i]
|
||||
for (let i = 0; i < action.packageNames.length; i++) {
|
||||
const packageName = action.packageNames[i]
|
||||
|
||||
if (packageName.indexOf(':') !== -1) {
|
||||
await assertCanAddApp(packageName.substring(0, packageName.indexOf(':')), true)
|
||||
await assertCanAddApp(packageName, false)
|
||||
} else {
|
||||
await assertCanAddApp(packageName, true)
|
||||
if (packageName.indexOf(':') !== -1) {
|
||||
await assertCanAddApp(packageName.substring(0, packageName.indexOf(':')), true)
|
||||
await assertCanAddApp(packageName, false)
|
||||
} else {
|
||||
await assertCanAddApp(packageName, true)
|
||||
}
|
||||
}
|
||||
} catch (ex) {
|
||||
if (ex instanceof GetParentCategoriesException) {
|
||||
throw new MissingCategoryException()
|
||||
} else throw ex
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
import { AddCategoryNetworkIdAction } from '../../../../action'
|
||||
import { maxNetworkIdsPerCategory } from '../../../../database/categorynetworkid'
|
||||
import { Cache } from '../cache'
|
||||
import { ApplyActionException } from '../exception/index'
|
||||
import { MissingCategoryException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchAddCategoryNetworkId ({ action, cache }: {
|
||||
action: AddCategoryNetworkIdAction
|
||||
@@ -33,7 +35,7 @@ export async function dispatchAddCategoryNetworkId ({ action, cache }: {
|
||||
})
|
||||
|
||||
if (!categoryEntryUnsafe) {
|
||||
throw new Error('invalid category id for new rule')
|
||||
throw new MissingCategoryException()
|
||||
}
|
||||
|
||||
const count = await cache.database.categoryNetworkId.count({
|
||||
@@ -45,7 +47,9 @@ export async function dispatchAddCategoryNetworkId ({ action, cache }: {
|
||||
})
|
||||
|
||||
if (count + 1 > maxNetworkIdsPerCategory) {
|
||||
throw new Error('category network limit reached')
|
||||
throw new ApplyActionException({
|
||||
staticMessage: 'can not add a category network id because the category network limit reached'
|
||||
})
|
||||
}
|
||||
|
||||
const hasOldItem = (await cache.database.categoryNetworkId.count({
|
||||
@@ -58,7 +62,9 @@ export async function dispatchAddCategoryNetworkId ({ action, cache }: {
|
||||
})) !== 0
|
||||
|
||||
if (hasOldItem) {
|
||||
throw new Error('id already used')
|
||||
throw new ApplyActionException({
|
||||
staticMessage: 'can not add a category network id because the id is already used'
|
||||
})
|
||||
}
|
||||
|
||||
await cache.database.categoryNetworkId.create({
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@@ -16,8 +16,10 @@
|
||||
*/
|
||||
|
||||
import * as Sequelize from 'sequelize'
|
||||
import { ChangeParentPasswordAction } from '../../../../action'
|
||||
import { ChangeParentPasswordAction, InvalidChangeParentPasswordIntegrityException } from '../../../../action/changeparentpassword'
|
||||
import { Cache } from '../cache'
|
||||
import { ApplyActionException } from '../exception/index'
|
||||
import { MissingUserException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchChangeParentPassword ({ action, cache }: {
|
||||
action: ChangeParentPasswordAction
|
||||
@@ -34,10 +36,17 @@ export async function dispatchChangeParentPassword ({ action, cache }: {
|
||||
})
|
||||
|
||||
if (!parentEntry) {
|
||||
throw new Error('parent entry not found')
|
||||
throw new MissingUserException()
|
||||
}
|
||||
|
||||
try {
|
||||
action.assertIntegrityValid({ oldPasswordSecondHash: parentEntry.secondPasswordHash })
|
||||
} catch (ex) {
|
||||
if (ex instanceof InvalidChangeParentPasswordIntegrityException) {
|
||||
throw new ApplyActionException({ staticMessage: 'invalid new password integrity' })
|
||||
} else throw ex
|
||||
}
|
||||
|
||||
action.assertIntegrityValid({ oldPasswordSecondHash: parentEntry.secondPasswordHash })
|
||||
const newSecondPasswordHash = action.decryptSecondHash({ oldPasswordSecondHash: parentEntry.secondPasswordHash })
|
||||
|
||||
parentEntry.passwordHash = action.newPasswordFirstHash
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
import { CreateCategoryAction } from '../../../../action'
|
||||
import { generateVersionId } from '../../../../util/token'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingUserException } from '../exception/missing-item'
|
||||
import { CanNotModifyOtherUsersBySelfLimitationException } from '../exception/self-limit'
|
||||
|
||||
export async function dispatchCreateCategory ({ action, cache, fromChildSelfLimitAddChildUserId }: {
|
||||
action: CreateCategoryAction
|
||||
@@ -26,7 +28,7 @@ export async function dispatchCreateCategory ({ action, cache, fromChildSelfLimi
|
||||
}) {
|
||||
if (fromChildSelfLimitAddChildUserId !== null) {
|
||||
if (fromChildSelfLimitAddChildUserId !== action.childId) {
|
||||
throw new Error('can not create categories for other child users')
|
||||
throw new CanNotModifyOtherUsersBySelfLimitationException()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +43,7 @@ export async function dispatchCreateCategory ({ action, cache, fromChildSelfLimi
|
||||
})
|
||||
|
||||
if (!childEntry) {
|
||||
throw new Error('missing child for new category')
|
||||
throw new MissingUserException()
|
||||
}
|
||||
|
||||
const oldMaxSort: number = await cache.database.category.max('sort', {
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
import { CreateTimeLimitRuleAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingCategoryException } from '../exception/missing-item'
|
||||
import { CanNotModifyOtherUsersBySelfLimitationException } from '../exception/self-limit'
|
||||
|
||||
export async function dispatchCreateTimeLimitRule ({ action, cache, fromChildSelfLimitAddChildUserId }: {
|
||||
action: CreateTimeLimitRuleAction
|
||||
@@ -33,12 +35,12 @@ export async function dispatchCreateTimeLimitRule ({ action, cache, fromChildSel
|
||||
})
|
||||
|
||||
if (!categoryEntryUnsafe) {
|
||||
throw new Error('invalid category id for new rule')
|
||||
throw new MissingCategoryException()
|
||||
}
|
||||
|
||||
if (fromChildSelfLimitAddChildUserId !== null) {
|
||||
if (fromChildSelfLimitAddChildUserId !== categoryEntryUnsafe.childId) {
|
||||
throw new Error('can not add rules for other users')
|
||||
throw new CanNotModifyOtherUsersBySelfLimitationException()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@@ -17,15 +17,25 @@
|
||||
|
||||
import { DeleteCategoryAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingCategoryException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchDeleteCategory ({ action, cache }: {
|
||||
action: DeleteCategoryAction
|
||||
cache: Cache
|
||||
}) {
|
||||
// no version number needs to be updated
|
||||
const { familyId, transaction } = cache
|
||||
const { categoryId } = action
|
||||
|
||||
const categoryEntry = await cache.database.category.findOne({
|
||||
where: {
|
||||
familyId,
|
||||
categoryId
|
||||
},
|
||||
transaction
|
||||
})
|
||||
|
||||
if (!categoryEntry) { throw new MissingCategoryException() }
|
||||
|
||||
await cache.database.timelimitRule.destroy({
|
||||
where: {
|
||||
familyId,
|
||||
@@ -75,4 +85,6 @@ export async function dispatchDeleteCategory ({ action, cache }: {
|
||||
if (affectedUserRows !== 0) {
|
||||
cache.invalidiateUserList = true
|
||||
}
|
||||
|
||||
// no version number needs to be updated
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
import { DeleteTimeLimitRuleAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingRuleException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchDeleteTimeLimitRule ({ action, cache }: {
|
||||
action: DeleteTimeLimitRuleAction
|
||||
@@ -30,10 +31,12 @@ export async function dispatchDeleteTimeLimitRule ({ action, cache }: {
|
||||
transaction: cache.transaction
|
||||
})
|
||||
|
||||
if (ruleEntry) {
|
||||
await ruleEntry.destroy({ transaction: cache.transaction })
|
||||
|
||||
cache.categoriesWithModifiedTimeLimitRules.push(ruleEntry.categoryId)
|
||||
cache.areChangesImportant = true
|
||||
if (!ruleEntry) {
|
||||
throw new MissingRuleException()
|
||||
}
|
||||
|
||||
await ruleEntry.destroy({ transaction: cache.transaction })
|
||||
|
||||
cache.categoriesWithModifiedTimeLimitRules.push(ruleEntry.categoryId)
|
||||
cache.areChangesImportant = true
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
import { IgnoreManipulationAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { SourceDeviceNotFoundException } from '../exception/illegal-state'
|
||||
|
||||
export async function dispatchIgnoreManipulation ({ action, cache }: {
|
||||
action: IgnoreManipulationAction
|
||||
@@ -31,7 +32,7 @@ export async function dispatchIgnoreManipulation ({ action, cache }: {
|
||||
})
|
||||
|
||||
if (deviceEntry === null) {
|
||||
throw new Error('illegal state: missing device which dispatched the action')
|
||||
throw new SourceDeviceNotFoundException()
|
||||
}
|
||||
|
||||
if (action.ignoreDeviceAdminManipulation) {
|
||||
|
||||
+4
-2
@@ -18,13 +18,15 @@
|
||||
import { IncrementCategoryExtraTimeAction } from '../../../../action'
|
||||
import { CategoryModel } from '../../../../database/category'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingCategoryException } from '../exception/missing-item'
|
||||
import { PremiumVersionMissingException } from '../exception/premium'
|
||||
|
||||
export async function dispatchIncrementCategoryExtraTime ({ action, cache }: {
|
||||
action: IncrementCategoryExtraTimeAction
|
||||
cache: Cache
|
||||
}) {
|
||||
if (!cache.hasFullVersion) {
|
||||
throw new Error('action requires full version')
|
||||
throw new PremiumVersionMissingException()
|
||||
}
|
||||
|
||||
async function handleCategory (category: CategoryModel) {
|
||||
@@ -51,7 +53,7 @@ export async function dispatchIncrementCategoryExtraTime ({ action, cache }: {
|
||||
})
|
||||
|
||||
if (!categoryEntry) {
|
||||
throw new Error(`tried to add extra time to ${action.categoryId} but it does not exist`)
|
||||
throw new MissingCategoryException()
|
||||
}
|
||||
|
||||
await handleCategory(categoryEntry)
|
||||
|
||||
@@ -62,6 +62,8 @@ import {
|
||||
UpdateUserLimitLoginCategory
|
||||
} from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { ActionObjectTypeNotHandledException } from '../exception/illegal-state'
|
||||
import { ActionNotSupportedBySelfLimitationException } from '../exception/self-limit'
|
||||
import { dispatchAddCategoryApps } from './addcategoryapps'
|
||||
import { dispatchAddCategoryNetworkId } from './addcategorynetworkid'
|
||||
import { dispatchAddUser } from './adduser'
|
||||
@@ -129,7 +131,9 @@ export const dispatchParentAction = async ({ action, cache, parentUserId, source
|
||||
return dispatchUpdateCategoryBlockedTimes({ action, cache, fromChildSelfLimitAddChildUserId })
|
||||
}
|
||||
|
||||
if (fromChildSelfLimitAddChildUserId === null) {
|
||||
if (fromChildSelfLimitAddChildUserId !== null) {
|
||||
throw new ActionNotSupportedBySelfLimitationException()
|
||||
} else {
|
||||
if (action instanceof AddCategoryNetworkIdAction) {
|
||||
return dispatchAddCategoryNetworkId({ action, cache })
|
||||
} else if (action instanceof AddUserAction) {
|
||||
@@ -202,8 +206,8 @@ export const dispatchParentAction = async ({ action, cache, parentUserId, source
|
||||
return dispatchUpdateUserFlagsAction({ action, cache })
|
||||
} else if (action instanceof UpdateUserLimitLoginCategory) {
|
||||
return dispatchUpdateUserLimitLoginCategoryAction({ action, cache, parentUserId })
|
||||
} else {
|
||||
throw new ActionObjectTypeNotHandledException()
|
||||
}
|
||||
} else {
|
||||
throw new Error('unsupported action type')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@@ -18,6 +18,7 @@
|
||||
import * as Sequelize from 'sequelize'
|
||||
import { RemoveCategoryAppsAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingItemException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchRemoveCategoryApps ({ action, cache }: {
|
||||
action: RemoveCategoryAppsAction
|
||||
@@ -35,7 +36,9 @@ export async function dispatchRemoveCategoryApps ({ action, cache }: {
|
||||
})
|
||||
|
||||
if (affectedRows !== action.packageNames.length) {
|
||||
throw new Error('could not delete as much entries as requested')
|
||||
throw new MissingItemException({
|
||||
staticMessage: 'could not remove all requested category app items'
|
||||
})
|
||||
}
|
||||
|
||||
cache.categoriesWithModifiedApps.push(action.categoryId)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@@ -21,6 +21,9 @@ import { difference } from 'lodash'
|
||||
import * as Sequelize from 'sequelize'
|
||||
import { RemoveUserAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { ApplyActionException } from '../exception/index'
|
||||
import { ApplyActionIntegrityException } from '../exception/integrity'
|
||||
import { MissingUserException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchRemoveUser ({ action, cache, parentUserId }: {
|
||||
action: RemoveUserAction
|
||||
@@ -36,7 +39,7 @@ export async function dispatchRemoveUser ({ action, cache, parentUserId }: {
|
||||
})
|
||||
|
||||
if (!user) {
|
||||
throw new Error('invalid user id')
|
||||
throw new MissingUserException()
|
||||
}
|
||||
|
||||
if (user.type === 'parent') {
|
||||
@@ -45,7 +48,7 @@ export async function dispatchRemoveUser ({ action, cache, parentUserId }: {
|
||||
}
|
||||
|
||||
if (parentUserId === action.userId) {
|
||||
throw new Error('users can not delete themself')
|
||||
throw new ApplyActionException({ staticMessage: 'users can not delete themself' })
|
||||
}
|
||||
|
||||
const expectedIntegrityValue = createHash('sha512').update(
|
||||
@@ -53,7 +56,7 @@ export async function dispatchRemoveUser ({ action, cache, parentUserId }: {
|
||||
).digest('hex').substring(0, 16)
|
||||
|
||||
if (expectedIntegrityValue !== action.authentication) {
|
||||
throw new Error('invalid authentication value')
|
||||
throw new ApplyActionIntegrityException({ staticMessage: 'invalid authentication value for removing a user' })
|
||||
}
|
||||
|
||||
if (user.mail !== '') {
|
||||
@@ -69,7 +72,7 @@ export async function dispatchRemoveUser ({ action, cache, parentUserId }: {
|
||||
})
|
||||
|
||||
if (usersWithLinkedMail <= 1) {
|
||||
throw new Error('this user is the last one with a linked mail address')
|
||||
throw new ApplyActionException({ staticMessage: 'this user is the last one with a linked mail address' })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +96,7 @@ export async function dispatchRemoveUser ({ action, cache, parentUserId }: {
|
||||
const allOtherParentUserIds = allParentUserIds.filter((item) => item !== action.userId)
|
||||
|
||||
if (difference(allOtherParentUserIds, usersWithLimitLoginCategories).length === 0) {
|
||||
throw new Error('can not delete the last user without limit login category')
|
||||
throw new ApplyActionException({ staticMessage: 'can not delete the last user without limit login category' })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@@ -17,12 +17,26 @@
|
||||
|
||||
import { RenameChildAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingUserException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchRenameChild ({ action, cache }: {
|
||||
action: RenameChildAction
|
||||
cache: Cache
|
||||
}) {
|
||||
const [affectedRows] = await cache.database.user.update({
|
||||
const oldItem = await cache.database.user.findOne({
|
||||
where: {
|
||||
familyId: cache.familyId,
|
||||
userId: action.childId,
|
||||
type: 'child'
|
||||
},
|
||||
transaction: cache.transaction
|
||||
})
|
||||
|
||||
if (!oldItem) {
|
||||
throw new MissingUserException()
|
||||
}
|
||||
|
||||
await cache.database.user.update({
|
||||
name: action.newName
|
||||
}, {
|
||||
where: {
|
||||
@@ -33,10 +47,6 @@ export async function dispatchRenameChild ({ action, cache }: {
|
||||
transaction: cache.transaction
|
||||
})
|
||||
|
||||
if (affectedRows !== 1) {
|
||||
throw new Error('can not update child name if child does not exist')
|
||||
}
|
||||
|
||||
cache.invalidiateUserList = true
|
||||
cache.doesUserExist.cache.set(action.childId, false)
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
import { ResetCategoryNetworkIdsAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingCategoryException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchResetCategoryNetworkIds ({ action, cache }: {
|
||||
action: ResetCategoryNetworkIdsAction
|
||||
@@ -32,7 +33,7 @@ export async function dispatchResetCategoryNetworkIds ({ action, cache }: {
|
||||
})
|
||||
|
||||
if (!categoryEntryUnsafe) {
|
||||
throw new Error('invalid category id for new rule')
|
||||
throw new MissingCategoryException()
|
||||
}
|
||||
|
||||
await cache.database.categoryNetworkId.destroy({
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@@ -17,12 +17,26 @@
|
||||
|
||||
import { ResetParentBlockedTimesAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingUserException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchResetParentBlockedTimes ({ action, cache }: {
|
||||
action: ResetParentBlockedTimesAction
|
||||
cache: Cache
|
||||
}) {
|
||||
const [affectedRows] = await cache.database.user.update({
|
||||
const oldItem = await cache.database.user.findOne({
|
||||
where: {
|
||||
familyId: cache.familyId,
|
||||
userId: action.parentId,
|
||||
type: 'parent'
|
||||
},
|
||||
transaction: cache.transaction
|
||||
})
|
||||
|
||||
if (!oldItem) {
|
||||
throw new MissingUserException()
|
||||
}
|
||||
|
||||
await cache.database.user.update({
|
||||
blockedTimes: ''
|
||||
}, {
|
||||
where: {
|
||||
@@ -33,10 +47,6 @@ export async function dispatchResetParentBlockedTimes ({ action, cache }: {
|
||||
transaction: cache.transaction
|
||||
})
|
||||
|
||||
if (affectedRows === 0) {
|
||||
throw new Error('invalid parent user id provided')
|
||||
}
|
||||
|
||||
cache.invalidiateUserList = true
|
||||
cache.areChangesImportant = true
|
||||
}
|
||||
|
||||
@@ -17,16 +17,30 @@
|
||||
|
||||
import { SetCategoryExtraTimeAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingCategoryException } from '../exception/missing-item'
|
||||
import { PremiumVersionMissingException } from '../exception/premium'
|
||||
|
||||
export async function dispatchSetCategoryExtraTime ({ action, cache }: {
|
||||
action: SetCategoryExtraTimeAction
|
||||
cache: Cache
|
||||
}) {
|
||||
if (!cache.hasFullVersion) {
|
||||
throw new Error('action requires full version')
|
||||
throw new PremiumVersionMissingException()
|
||||
}
|
||||
|
||||
const [affectedRows] = await cache.database.category.update({
|
||||
const oldItem = await cache.database.category.findOne({
|
||||
where: {
|
||||
familyId: cache.familyId,
|
||||
categoryId: action.categoryId
|
||||
},
|
||||
transaction: cache.transaction
|
||||
})
|
||||
|
||||
if (!oldItem) {
|
||||
throw new MissingCategoryException()
|
||||
}
|
||||
|
||||
await cache.database.category.update({
|
||||
extraTimeInMillis: action.newExtraTime,
|
||||
extraTimeDay: action.day
|
||||
}, {
|
||||
@@ -37,8 +51,6 @@ export async function dispatchSetCategoryExtraTime ({ action, cache }: {
|
||||
transaction: cache.transaction
|
||||
})
|
||||
|
||||
if (affectedRows !== 0) {
|
||||
cache.categoriesWithModifiedBaseData.push(action.categoryId)
|
||||
cache.areChangesImportant = true
|
||||
}
|
||||
cache.categoriesWithModifiedBaseData.push(action.categoryId)
|
||||
cache.areChangesImportant = true
|
||||
}
|
||||
|
||||
+23
-8
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@@ -17,11 +17,26 @@
|
||||
|
||||
import { SetCategoryForUnassignedAppsAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { ApplyActionException } from '../exception/index'
|
||||
import { MissingUserException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchSetCategoryForUnassignedApps ({ action, cache }: {
|
||||
action: SetCategoryForUnassignedAppsAction
|
||||
cache: Cache
|
||||
}) {
|
||||
const oldUserEntry = await cache.database.user.findOne({
|
||||
where: {
|
||||
familyId: cache.familyId,
|
||||
userId: action.childId,
|
||||
type: 'child'
|
||||
},
|
||||
transaction: cache.transaction
|
||||
})
|
||||
|
||||
if (!oldUserEntry) {
|
||||
throw new MissingUserException()
|
||||
}
|
||||
|
||||
if (action.categoryId === '') {
|
||||
// nothing to check
|
||||
} else {
|
||||
@@ -35,7 +50,9 @@ export async function dispatchSetCategoryForUnassignedApps ({ action, cache }: {
|
||||
})
|
||||
|
||||
if (!categoryEntryUnsafe) {
|
||||
throw new Error('can not set a category which does not exist as category for unassigned apps')
|
||||
throw new ApplyActionException({
|
||||
staticMessage: 'can not set a category which does not exist as category for unassigned apps'
|
||||
})
|
||||
}
|
||||
|
||||
const categoryEntry = {
|
||||
@@ -43,11 +60,13 @@ export async function dispatchSetCategoryForUnassignedApps ({ action, cache }: {
|
||||
}
|
||||
|
||||
if (categoryEntry.childId !== action.childId) {
|
||||
throw new Error('can not set a category of one child as category for unassigned apps for an other child')
|
||||
throw new ApplyActionException({
|
||||
staticMessage: 'can not set a category of one child as category for unassigned apps for an other child'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const [affectedRows] = await cache.database.user.update({
|
||||
await cache.database.user.update({
|
||||
categoryForNotAssignedApps: action.categoryId
|
||||
}, {
|
||||
where: {
|
||||
@@ -58,10 +77,6 @@ export async function dispatchSetCategoryForUnassignedApps ({ action, cache }: {
|
||||
transaction: cache.transaction
|
||||
})
|
||||
|
||||
if (affectedRows !== 1) {
|
||||
throw new Error('could not find a child with matching id for setting the category for not assigned apps')
|
||||
}
|
||||
|
||||
cache.invalidiateUserList = true
|
||||
cache.areChangesImportant = true
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@@ -18,6 +18,7 @@
|
||||
import * as Sequelize from 'sequelize'
|
||||
import { SetChildPasswordAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingUserException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchSetChildPassword ({ action, cache }: {
|
||||
action: SetChildPasswordAction
|
||||
@@ -34,7 +35,7 @@ export async function dispatchSetChildPassword ({ action, cache }: {
|
||||
})
|
||||
|
||||
if (!childEntry) {
|
||||
throw new Error('parent entry not found')
|
||||
throw new MissingUserException()
|
||||
}
|
||||
|
||||
childEntry.passwordHash = action.newPassword.hash
|
||||
|
||||
+15
-6
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@@ -17,12 +17,25 @@
|
||||
|
||||
import { SetConsiderRebootManipulationAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingDeviceException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchSetConsiderRebootManipulation ({ action, cache }: {
|
||||
action: SetConsiderRebootManipulationAction
|
||||
cache: Cache
|
||||
}) {
|
||||
const [affectedRows] = await cache.database.device.update({
|
||||
const oldDevice = await cache.database.device.findOne({
|
||||
transaction: cache.transaction,
|
||||
where: {
|
||||
familyId: cache.familyId,
|
||||
deviceId: action.deviceId
|
||||
}
|
||||
})
|
||||
|
||||
if (!oldDevice) {
|
||||
throw new MissingDeviceException()
|
||||
}
|
||||
|
||||
await cache.database.device.update({
|
||||
considerRebootManipulation: action.enable
|
||||
}, {
|
||||
transaction: cache.transaction,
|
||||
@@ -32,10 +45,6 @@ export async function dispatchSetConsiderRebootManipulation ({ action, cache }:
|
||||
}
|
||||
})
|
||||
|
||||
if (affectedRows === 0) {
|
||||
throw new Error('did not find device to update consider reboot manipulation')
|
||||
}
|
||||
|
||||
cache.invalidiateDeviceList = true
|
||||
cache.areChangesImportant = true
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
import { SetDeviceDefaultUserAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingDeviceException, MissingUserException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchSetDeviceDefaultUser ({ action, cache }: {
|
||||
action: SetDeviceDefaultUserAction
|
||||
@@ -26,11 +27,23 @@ export async function dispatchSetDeviceDefaultUser ({ action, cache }: {
|
||||
const doesUserExist = await cache.doesUserExist(action.defaultUserId)
|
||||
|
||||
if (!doesUserExist) {
|
||||
throw new Error('can not set invalid user as default user')
|
||||
throw new MissingUserException()
|
||||
}
|
||||
}
|
||||
|
||||
const [affectedRows] = await cache.database.device.update({
|
||||
const oldDeviceItem = await cache.database.device.findOne({
|
||||
transaction: cache.transaction,
|
||||
where: {
|
||||
familyId: cache.familyId,
|
||||
deviceId: action.deviceId
|
||||
}
|
||||
})
|
||||
|
||||
if (!oldDeviceItem) {
|
||||
throw new MissingDeviceException()
|
||||
}
|
||||
|
||||
await cache.database.device.update({
|
||||
defaultUserId: action.defaultUserId
|
||||
}, {
|
||||
transaction: cache.transaction,
|
||||
@@ -40,10 +53,6 @@ export async function dispatchSetDeviceDefaultUser ({ action, cache }: {
|
||||
}
|
||||
})
|
||||
|
||||
if (affectedRows === 0) {
|
||||
throw new Error('did not find device to update default user')
|
||||
}
|
||||
|
||||
cache.invalidiateDeviceList = true
|
||||
cache.areChangesImportant = true
|
||||
}
|
||||
|
||||
+15
-6
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@@ -17,12 +17,25 @@
|
||||
|
||||
import { SetDeviceDefaultUserTimeoutAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingDeviceException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchSetDeviceDefaultUserTimeout ({ action, cache }: {
|
||||
action: SetDeviceDefaultUserTimeoutAction
|
||||
cache: Cache
|
||||
}) {
|
||||
const [affectedRows] = await cache.database.device.update({
|
||||
const oldDeviceItem = await cache.database.device.findOne({
|
||||
transaction: cache.transaction,
|
||||
where: {
|
||||
familyId: cache.familyId,
|
||||
deviceId: action.deviceId
|
||||
}
|
||||
})
|
||||
|
||||
if (!oldDeviceItem) {
|
||||
throw new MissingDeviceException()
|
||||
}
|
||||
|
||||
await cache.database.device.update({
|
||||
defaultUserTimeout: action.timeout
|
||||
}, {
|
||||
transaction: cache.transaction,
|
||||
@@ -32,10 +45,6 @@ export async function dispatchSetDeviceDefaultUserTimeout ({ action, cache }: {
|
||||
}
|
||||
})
|
||||
|
||||
if (affectedRows === 0) {
|
||||
throw new Error('did not find device to update default user timeout')
|
||||
}
|
||||
|
||||
cache.invalidiateDeviceList = true
|
||||
cache.areChangesImportant = true
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
import { SetDeviceUserAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingDeviceException, MissingUserException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchSetDeviceUser ({ action, cache }: {
|
||||
action: SetDeviceUserAction
|
||||
@@ -26,11 +27,23 @@ export async function dispatchSetDeviceUser ({ action, cache }: {
|
||||
const doesUserExist = await cache.doesUserExist(action.userId)
|
||||
|
||||
if (!doesUserExist) {
|
||||
throw new Error('invalid user id provided')
|
||||
throw new MissingUserException()
|
||||
}
|
||||
}
|
||||
|
||||
const [affectedRows] = await cache.database.device.update({
|
||||
const oldDeviceItem = await cache.database.device.findOne({
|
||||
where: {
|
||||
familyId: cache.familyId,
|
||||
deviceId: action.deviceId
|
||||
},
|
||||
transaction: cache.transaction
|
||||
})
|
||||
|
||||
if (!oldDeviceItem) {
|
||||
throw new MissingDeviceException()
|
||||
}
|
||||
|
||||
await cache.database.device.update({
|
||||
currentUserId: action.userId,
|
||||
isUserKeptSignedIn: false
|
||||
}, {
|
||||
@@ -41,8 +54,6 @@ export async function dispatchSetDeviceUser ({ action, cache }: {
|
||||
transaction: cache.transaction
|
||||
})
|
||||
|
||||
if (affectedRows !== 0) {
|
||||
cache.invalidiateDeviceList = true
|
||||
cache.areChangesImportant = true
|
||||
}
|
||||
cache.invalidiateDeviceList = true
|
||||
cache.areChangesImportant = true
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@@ -17,6 +17,9 @@
|
||||
|
||||
import { SetKeepSignedInAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { SourceUserNotFoundException } from '../exception/illegal-state'
|
||||
import { ApplyActionException } from '../exception/index'
|
||||
import { MissingDeviceException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchSetKeepSignedIn ({ action, cache, parentUserId }: {
|
||||
action: SetKeepSignedInAction
|
||||
@@ -26,7 +29,7 @@ export async function dispatchSetKeepSignedIn ({ action, cache, parentUserId }:
|
||||
const doesUserExist = await cache.doesUserExist(parentUserId)
|
||||
|
||||
if (!doesUserExist) {
|
||||
throw new Error('invalid user id provided')
|
||||
throw new SourceUserNotFoundException()
|
||||
}
|
||||
|
||||
const deviceEntry = await cache.database.device.findOne({
|
||||
@@ -38,12 +41,12 @@ export async function dispatchSetKeepSignedIn ({ action, cache, parentUserId }:
|
||||
})
|
||||
|
||||
if (!deviceEntry) {
|
||||
throw new Error('device does not exist')
|
||||
throw new MissingDeviceException()
|
||||
}
|
||||
|
||||
if (deviceEntry.currentUserId !== parentUserId) {
|
||||
if (action.keepSignedIn) {
|
||||
throw new Error('only the user itself can disable asking for the password')
|
||||
throw new ApplyActionException({ staticMessage: 'only the user itself can disable asking for the password' })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,11 @@
|
||||
*/
|
||||
|
||||
import { SetParentCategoryAction } from '../../../../action'
|
||||
import { getCategoryWithParentCategories } from '../../../../util/category'
|
||||
import { getCategoryWithParentCategories, GetParentCategoriesException } from '../../../../util/category'
|
||||
import { Cache } from '../cache'
|
||||
import { ApplyActionException } from '../exception/index'
|
||||
import { MissingCategoryException } from '../exception/missing-item'
|
||||
import { CanNotModifyOtherUsersBySelfLimitationException, SelfLimitationException } from '../exception/self-limit'
|
||||
|
||||
export async function dispatchSetParentCategory ({ action, cache, fromChildSelfLimitAddChildUserId }: {
|
||||
action: SetParentCategoryAction
|
||||
@@ -33,12 +36,12 @@ export async function dispatchSetParentCategory ({ action, cache, fromChildSelfL
|
||||
})
|
||||
|
||||
if (!categoryEntry) {
|
||||
throw new Error('tried to set parent category of non existent category')
|
||||
throw new MissingCategoryException()
|
||||
}
|
||||
|
||||
if (fromChildSelfLimitAddChildUserId !== null) {
|
||||
if (categoryEntry.childId !== fromChildSelfLimitAddChildUserId) {
|
||||
throw new Error('can not set parent category for other user')
|
||||
throw new CanNotModifyOtherUsersBySelfLimitationException()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +59,7 @@ export async function dispatchSetParentCategory ({ action, cache, fromChildSelfL
|
||||
}))
|
||||
|
||||
if (categoriesByUserId.find((item) => item.categoryId === action.parentCategory) === undefined) {
|
||||
throw new Error('selected parent category does not exist')
|
||||
throw new MissingCategoryException()
|
||||
}
|
||||
|
||||
const childCategoryIds = new Set<string>()
|
||||
@@ -80,16 +83,26 @@ export async function dispatchSetParentCategory ({ action, cache, fromChildSelfL
|
||||
}
|
||||
|
||||
if (childCategoryIds.has(action.parentCategory) || action.parentCategory === action.categoryId) {
|
||||
throw new Error('can not set a category as parent which is a child of the category')
|
||||
throw new ApplyActionException({
|
||||
staticMessage: 'can not set a category as parent which is a child of the category'
|
||||
})
|
||||
}
|
||||
|
||||
if (fromChildSelfLimitAddChildUserId !== null) {
|
||||
const ownParentCategory = categoriesByUserId.find((item) => item.categoryId === categoryEntry.parentCategoryId)
|
||||
const enableDueToLimitAddingWhenChild = ownParentCategory === undefined ||
|
||||
getCategoryWithParentCategories(categoriesByUserId, action.parentCategory).indexOf(ownParentCategory.categoryId) !== -1
|
||||
try {
|
||||
const ownParentCategory = categoriesByUserId.find((item) => item.categoryId === categoryEntry.parentCategoryId)
|
||||
const enableDueToLimitAddingWhenChild = ownParentCategory === undefined ||
|
||||
getCategoryWithParentCategories(categoriesByUserId, action.parentCategory).indexOf(ownParentCategory.categoryId) !== -1
|
||||
|
||||
if (!enableDueToLimitAddingWhenChild) {
|
||||
throw new Error('can not change parent categories in a way which reduces limits')
|
||||
if (!enableDueToLimitAddingWhenChild) {
|
||||
throw new SelfLimitationException({
|
||||
staticMessage: 'can not change parent categories in a way which reduces limits'
|
||||
})
|
||||
}
|
||||
} catch (ex) {
|
||||
if (ex instanceof GetParentCategoriesException) {
|
||||
throw new MissingCategoryException()
|
||||
} else throw ex
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@@ -17,12 +17,26 @@
|
||||
|
||||
import { SetRelaxPrimaryDeviceAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingUserException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchSetRelaxPrimaryDevice ({ action, cache }: {
|
||||
action: SetRelaxPrimaryDeviceAction
|
||||
cache: Cache
|
||||
}) {
|
||||
const [affectedRows] = await cache.database.user.update({
|
||||
const oldUser = cache.database.user.findOne({
|
||||
transaction: cache.transaction,
|
||||
where: {
|
||||
familyId: cache.familyId,
|
||||
userId: action.userId,
|
||||
type: 'child'
|
||||
}
|
||||
})
|
||||
|
||||
if (!oldUser) {
|
||||
throw new MissingUserException()
|
||||
}
|
||||
|
||||
await cache.database.user.update({
|
||||
relaxPrimaryDeviceRule: action.relax
|
||||
}, {
|
||||
transaction: cache.transaction,
|
||||
@@ -33,10 +47,6 @@ export async function dispatchSetRelaxPrimaryDevice ({ action, cache }: {
|
||||
}
|
||||
})
|
||||
|
||||
if (affectedRows === 0) {
|
||||
throw new Error('did not find user to update relax primary device')
|
||||
}
|
||||
|
||||
cache.invalidiateUserList = true
|
||||
cache.areChangesImportant = true
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
import { SetSendDeviceConnected } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { ApplyActionException } from '../exception/index'
|
||||
|
||||
export async function dispatchSetSendDeviceConnected ({ action, cache, sourceDeviceId }: {
|
||||
action: SetSendDeviceConnected
|
||||
@@ -24,10 +25,12 @@ export async function dispatchSetSendDeviceConnected ({ action, cache, sourceDev
|
||||
sourceDeviceId: string | null
|
||||
}) {
|
||||
if (sourceDeviceId === null || action.deviceId !== sourceDeviceId) {
|
||||
throw new Error('only can do that from the device itself')
|
||||
throw new ApplyActionException({
|
||||
staticMessage: 'only can do that from the device itself if the connection status should be sent'
|
||||
})
|
||||
}
|
||||
|
||||
const [affectedRows] = await cache.database.device.update({
|
||||
await cache.database.device.update({
|
||||
showDeviceConnected: action.enable
|
||||
}, {
|
||||
transaction: cache.transaction,
|
||||
@@ -37,10 +40,6 @@ export async function dispatchSetSendDeviceConnected ({ action, cache, sourceDev
|
||||
}
|
||||
})
|
||||
|
||||
if (affectedRows === 0) {
|
||||
throw new Error('did not find device to update send if connected')
|
||||
}
|
||||
|
||||
cache.devicesWithModifiedShowDeviceConnected.set(action.deviceId, action.enable)
|
||||
cache.invalidiateDeviceList = true
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
import { SetUserDisableLimitsUntilAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingUserException } from '../exception/missing-item'
|
||||
import { PremiumVersionMissingException } from '../exception/premium'
|
||||
|
||||
export async function dispatchUserSetDisableLimitsUntil ({ action, cache }: {
|
||||
action: SetUserDisableLimitsUntilAction
|
||||
@@ -24,11 +26,24 @@ export async function dispatchUserSetDisableLimitsUntil ({ action, cache }: {
|
||||
}) {
|
||||
if (action.timestamp !== 0) {
|
||||
if (!cache.hasFullVersion) {
|
||||
throw new Error('action requires full version')
|
||||
throw new PremiumVersionMissingException()
|
||||
}
|
||||
}
|
||||
|
||||
const [affectedRows] = await cache.database.user.update({
|
||||
const oldUser = await cache.database.user.findOne({
|
||||
where: {
|
||||
familyId: cache.familyId,
|
||||
userId: action.childId,
|
||||
type: 'child'
|
||||
},
|
||||
transaction: cache.transaction
|
||||
})
|
||||
|
||||
if (!oldUser) {
|
||||
throw new MissingUserException()
|
||||
}
|
||||
|
||||
await cache.database.user.update({
|
||||
disableTimelimitsUntil: action.timestamp.toString(10)
|
||||
}, {
|
||||
where: {
|
||||
@@ -39,10 +54,6 @@ export async function dispatchUserSetDisableLimitsUntil ({ action, cache }: {
|
||||
transaction: cache.transaction
|
||||
})
|
||||
|
||||
if (affectedRows === 0) {
|
||||
throw new Error('invalid user id provided')
|
||||
}
|
||||
|
||||
cache.invalidiateUserList = true
|
||||
cache.areChangesImportant = true
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@@ -17,12 +17,25 @@
|
||||
|
||||
import { SetUserTimezoneAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingUserException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchSetUserTimezone ({ action, cache }: {
|
||||
action: SetUserTimezoneAction
|
||||
cache: Cache
|
||||
}) {
|
||||
const [affectedRows] = await cache.database.user.update({
|
||||
const oldUser = await cache.database.user.findOne({
|
||||
where: {
|
||||
familyId: cache.familyId,
|
||||
userId: action.userId
|
||||
},
|
||||
transaction: cache.transaction
|
||||
})
|
||||
|
||||
if (!oldUser) {
|
||||
throw new MissingUserException()
|
||||
}
|
||||
|
||||
await cache.database.user.update({
|
||||
timeZone: action.timezone
|
||||
}, {
|
||||
transaction: cache.transaction,
|
||||
@@ -32,10 +45,6 @@ export async function dispatchSetUserTimezone ({ action, cache }: {
|
||||
}
|
||||
})
|
||||
|
||||
if (affectedRows === 0) {
|
||||
throw new Error('did not find user to update timezone')
|
||||
}
|
||||
|
||||
cache.invalidiateUserList = true
|
||||
cache.areChangesImportant = true
|
||||
}
|
||||
|
||||
+2
-1
@@ -17,6 +17,7 @@
|
||||
|
||||
import { UpdateCategoryBatteryLimitAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingCategoryException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchUpdateCategoryBatteryLimit ({ action, cache }: {
|
||||
action: UpdateCategoryBatteryLimitAction
|
||||
@@ -31,7 +32,7 @@ export async function dispatchUpdateCategoryBatteryLimit ({ action, cache }: {
|
||||
})
|
||||
|
||||
if (!categoryEntry) {
|
||||
throw new Error('invalid category id')
|
||||
throw new MissingCategoryException()
|
||||
}
|
||||
|
||||
if (action.chargeLimit !== undefined) {
|
||||
|
||||
+5
-3
@@ -17,6 +17,8 @@
|
||||
|
||||
import { UpdateCategoryBlockAllNotificationsAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingCategoryException } from '../exception/missing-item'
|
||||
import { CanNotModifyOtherUsersBySelfLimitationException, SelfLimitationException } from '../exception/self-limit'
|
||||
|
||||
export async function dispatchUpdateCategoryBlockAllNotifications ({ action, cache, fromChildSelfLimitAddChildUserId }: {
|
||||
action: UpdateCategoryBlockAllNotificationsAction
|
||||
@@ -33,16 +35,16 @@ export async function dispatchUpdateCategoryBlockAllNotifications ({ action, cac
|
||||
})
|
||||
|
||||
if (!categoryEntryUnsafe) {
|
||||
throw new Error('invalid category id for updating notification blocking')
|
||||
throw new MissingCategoryException()
|
||||
}
|
||||
|
||||
if (fromChildSelfLimitAddChildUserId !== null) {
|
||||
if (fromChildSelfLimitAddChildUserId !== categoryEntryUnsafe.childId) {
|
||||
throw new Error('can not add rules for other users')
|
||||
throw new CanNotModifyOtherUsersBySelfLimitationException()
|
||||
}
|
||||
|
||||
if (!action.blocked) {
|
||||
throw new Error('can not disable filter as child')
|
||||
throw new SelfLimitationException({ staticMessage: 'can not disable notification filter as child' })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-3
@@ -18,6 +18,8 @@
|
||||
import { blockedTimesBitmaskLength, UpdateCategoryBlockedTimesAction } from '../../../../action/updatecategoryblockedtimes'
|
||||
import { validateAndParseBitmask } from '../../../../util/bitmask'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingCategoryException } from '../exception/missing-item'
|
||||
import { CanNotModifyOtherUsersBySelfLimitationException, SelfLimitationException } from '../exception/self-limit'
|
||||
|
||||
export async function dispatchUpdateCategoryBlockedTimes ({ action, cache, fromChildSelfLimitAddChildUserId }: {
|
||||
action: UpdateCategoryBlockedTimesAction
|
||||
@@ -34,7 +36,7 @@ export async function dispatchUpdateCategoryBlockedTimes ({ action, cache, fromC
|
||||
})
|
||||
|
||||
if (!categoryEntryUnsafe) {
|
||||
throw new Error('can not update blocked time areas for a category which does not exist')
|
||||
throw new MissingCategoryException()
|
||||
}
|
||||
|
||||
const categoryEntry = {
|
||||
@@ -44,7 +46,7 @@ export async function dispatchUpdateCategoryBlockedTimes ({ action, cache, fromC
|
||||
|
||||
if (fromChildSelfLimitAddChildUserId !== null) {
|
||||
if (categoryEntry.childId !== fromChildSelfLimitAddChildUserId) {
|
||||
throw new Error('can not update blocked time areas for other child users')
|
||||
throw new CanNotModifyOtherUsersBySelfLimitationException()
|
||||
}
|
||||
|
||||
const oldBlocked = validateAndParseBitmask(categoryEntry.blockedMinutesInWeek, blockedTimesBitmaskLength)
|
||||
@@ -52,7 +54,7 @@ export async function dispatchUpdateCategoryBlockedTimes ({ action, cache, fromC
|
||||
|
||||
oldBlocked.forEach((value, index) => {
|
||||
if (value && !newBlocked[index]) {
|
||||
throw new Error('new blocked time areas are smaller')
|
||||
throw new SelfLimitationException({ staticMessage: 'new blocked time areas are smaller' })
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
+8
-5
@@ -17,6 +17,9 @@
|
||||
|
||||
import { UpdateCategoryTemporarilyBlockedAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingCategoryException } from '../exception/missing-item'
|
||||
import { PremiumVersionMissingException } from '../exception/premium'
|
||||
import { CanNotModifyOtherUsersBySelfLimitationException, SelfLimitationException } from '../exception/self-limit'
|
||||
|
||||
export async function dispatchUpdateCategoryTemporarilyBlocked ({ action, cache, fromChildSelfLimitAddChildUserId }: {
|
||||
action: UpdateCategoryTemporarilyBlockedAction
|
||||
@@ -25,7 +28,7 @@ export async function dispatchUpdateCategoryTemporarilyBlocked ({ action, cache,
|
||||
}) {
|
||||
if (action.blocked === true) {
|
||||
if (!cache.hasFullVersion) {
|
||||
throw new Error('action requires full version')
|
||||
throw new PremiumVersionMissingException()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +42,7 @@ export async function dispatchUpdateCategoryTemporarilyBlocked ({ action, cache,
|
||||
})
|
||||
|
||||
if (!categoryEntryUnsafe) {
|
||||
throw new Error('invalid category id for updating temporarily blocking')
|
||||
throw new MissingCategoryException()
|
||||
}
|
||||
|
||||
const categoryEntry = {
|
||||
@@ -50,16 +53,16 @@ export async function dispatchUpdateCategoryTemporarilyBlocked ({ action, cache,
|
||||
|
||||
if (fromChildSelfLimitAddChildUserId !== null) {
|
||||
if (fromChildSelfLimitAddChildUserId !== categoryEntry.childId) {
|
||||
throw new Error('can not update temporarily blocking as child for other users')
|
||||
throw new CanNotModifyOtherUsersBySelfLimitationException()
|
||||
}
|
||||
|
||||
if (action.endTime === undefined || !action.blocked) {
|
||||
throw new Error('the child may only enable a temporarily blocking')
|
||||
throw new SelfLimitationException({ staticMessage: 'the child may only enable a temporarily blocking' })
|
||||
}
|
||||
|
||||
if (categoryEntry.temporarilyBlocked) {
|
||||
if (action.endTime < categoryEntry.temporarilyBlockedEndTime || categoryEntry.temporarilyBlockedEndTime === 0) {
|
||||
throw new Error('the child may not reduce the temporarily blocking')
|
||||
throw new SelfLimitationException({ staticMessage: 'the child may not reduce the temporarily blocking' })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
import { UpdateCategoryTimeWarningsAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingCategoryException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchUpdateCategoryTimeWarnings ({ action, cache }: {
|
||||
action: UpdateCategoryTimeWarningsAction
|
||||
@@ -31,7 +32,7 @@ export async function dispatchUpdateCategoryTimeWarnings ({ action, cache }: {
|
||||
})
|
||||
|
||||
if (!categoryEntry) {
|
||||
throw new Error('invalid category id')
|
||||
throw new MissingCategoryException()
|
||||
}
|
||||
|
||||
if (action.enable) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@@ -17,11 +17,24 @@
|
||||
|
||||
import { UpdateCategoryTitleAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingCategoryException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchUpdateCategoryTitle ({ action, cache }: {
|
||||
action: UpdateCategoryTitleAction
|
||||
cache: Cache
|
||||
}) {
|
||||
const oldCategory = await cache.database.category.findOne({
|
||||
where: {
|
||||
familyId: cache.familyId,
|
||||
categoryId: action.categoryId
|
||||
},
|
||||
transaction: cache.transaction
|
||||
})
|
||||
|
||||
if (!oldCategory) {
|
||||
throw new MissingCategoryException()
|
||||
}
|
||||
|
||||
const [affectedRows] = await cache.database.category.update({
|
||||
title: action.newTitle
|
||||
}, {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@@ -17,11 +17,24 @@
|
||||
|
||||
import { UpdateDeviceNameAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingDeviceException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchUpdateDeviceName ({ action, cache }: {
|
||||
action: UpdateDeviceNameAction
|
||||
cache: Cache
|
||||
}) {
|
||||
const oldDevice = await cache.database.device.findOne({
|
||||
where: {
|
||||
familyId: cache.familyId,
|
||||
deviceId: action.deviceId
|
||||
},
|
||||
transaction: cache.transaction
|
||||
})
|
||||
|
||||
if (!oldDevice) {
|
||||
throw new MissingDeviceException()
|
||||
}
|
||||
|
||||
const [affectedRows] = await cache.database.device.update({
|
||||
name: action.name
|
||||
}, {
|
||||
@@ -32,9 +45,7 @@ export async function dispatchUpdateDeviceName ({ action, cache }: {
|
||||
transaction: cache.transaction
|
||||
})
|
||||
|
||||
if (affectedRows === 0) {
|
||||
throw new Error('invalid device id')
|
||||
} else {
|
||||
if (affectedRows !== 0) {
|
||||
cache.invalidiateDeviceList = true
|
||||
cache.areChangesImportant = true
|
||||
}
|
||||
|
||||
+15
-6
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@@ -17,12 +17,25 @@
|
||||
|
||||
import { UpdateEnableActivityLevelBlockingAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingDeviceException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchUpdateEnableActivityLevelBlocking ({ action, cache }: {
|
||||
action: UpdateEnableActivityLevelBlockingAction
|
||||
cache: Cache
|
||||
}) {
|
||||
const [affectedRows] = await cache.database.device.update({
|
||||
const oldDevice = await cache.database.device.findOne({
|
||||
transaction: cache.transaction,
|
||||
where: {
|
||||
familyId: cache.familyId,
|
||||
deviceId: action.deviceId
|
||||
}
|
||||
})
|
||||
|
||||
if (!oldDevice) {
|
||||
throw new MissingDeviceException()
|
||||
}
|
||||
|
||||
await cache.database.device.update({
|
||||
activityLevelBlocking: action.enable
|
||||
}, {
|
||||
transaction: cache.transaction,
|
||||
@@ -32,10 +45,6 @@ export async function dispatchUpdateEnableActivityLevelBlocking ({ action, cache
|
||||
}
|
||||
})
|
||||
|
||||
if (affectedRows === 0) {
|
||||
throw new Error('did not find device to update activity level blocking')
|
||||
}
|
||||
|
||||
cache.invalidiateDeviceList = true
|
||||
cache.areChangesImportant = true
|
||||
}
|
||||
|
||||
+13
@@ -17,11 +17,24 @@
|
||||
|
||||
import { UpdateNetworkTimeVerificationAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingDeviceException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchUpdateNetworkTimeVerification ({ action, cache }: {
|
||||
action: UpdateNetworkTimeVerificationAction
|
||||
cache: Cache
|
||||
}) {
|
||||
const oldDevice = await cache.database.device.findOne({
|
||||
transaction: cache.transaction,
|
||||
where: {
|
||||
familyId: cache.familyId,
|
||||
deviceId: action.deviceId
|
||||
}
|
||||
})
|
||||
|
||||
if (!oldDevice) {
|
||||
throw new MissingDeviceException()
|
||||
}
|
||||
|
||||
await cache.database.device.update({
|
||||
networkTime: action.mode
|
||||
}, {
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
import { UpdateParentBlockedTimesAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { ApplyActionException } from '../exception/index'
|
||||
import { MissingUserException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchUpdateParentBlockedTimes ({ action, cache, parentUserId }: {
|
||||
action: UpdateParentBlockedTimesAction
|
||||
@@ -24,10 +26,23 @@ export async function dispatchUpdateParentBlockedTimes ({ action, cache, parentU
|
||||
parentUserId: string
|
||||
}) {
|
||||
if (parentUserId !== action.parentId && action.blockedTimes !== '') {
|
||||
throw new Error('only a parent itself can add limits')
|
||||
throw new ApplyActionException({ staticMessage: 'only a parent itself can add limits' })
|
||||
}
|
||||
|
||||
const [affectedRows] = await cache.database.user.update({
|
||||
const oldUser = await cache.database.user.findOne({
|
||||
where: {
|
||||
familyId: cache.familyId,
|
||||
userId: action.parentId,
|
||||
type: 'parent'
|
||||
},
|
||||
transaction: cache.transaction
|
||||
})
|
||||
|
||||
if (!oldUser) {
|
||||
throw new MissingUserException()
|
||||
}
|
||||
|
||||
await cache.database.user.update({
|
||||
blockedTimes: action.blockedTimes
|
||||
}, {
|
||||
where: {
|
||||
@@ -38,10 +53,6 @@ export async function dispatchUpdateParentBlockedTimes ({ action, cache, parentU
|
||||
transaction: cache.transaction
|
||||
})
|
||||
|
||||
if (affectedRows === 0) {
|
||||
throw new Error('invalid parent user id provided')
|
||||
}
|
||||
|
||||
cache.invalidiateUserList = true
|
||||
cache.areChangesImportant = true
|
||||
}
|
||||
|
||||
+3
-2
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
import { UpdateParentNotificationFlagsAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingUserException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchUpdateParentNotificationFlags ({ action, cache }: {
|
||||
action: UpdateParentNotificationFlagsAction
|
||||
@@ -32,7 +33,7 @@ export async function dispatchUpdateParentNotificationFlags ({ action, cache }:
|
||||
})
|
||||
|
||||
if (!parentEntry) {
|
||||
throw new Error('parent not found')
|
||||
throw new MissingUserException()
|
||||
}
|
||||
|
||||
if (action.set) {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
import { UpdateTimelimitRuleAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { MissingRuleException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchUpdateTimelimitRule ({ action, cache }: {
|
||||
action: UpdateTimelimitRuleAction
|
||||
@@ -31,7 +32,7 @@ export async function dispatchUpdateTimelimitRule ({ action, cache }: {
|
||||
})
|
||||
|
||||
if (!ruleEntry) {
|
||||
throw new Error('invalid rule id provided')
|
||||
throw new MissingRuleException()
|
||||
}
|
||||
|
||||
ruleEntry.applyToExtraTimeUsage = action.applyToExtraTimeUsage
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* 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
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
@@ -17,6 +17,8 @@
|
||||
|
||||
import { UpdateUserFlagsAction } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { IllegalStateException } from '../exception/illegal-state'
|
||||
import { MissingUserException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchUpdateUserFlagsAction ({ action, cache }: {
|
||||
action: UpdateUserFlagsAction
|
||||
@@ -31,13 +33,13 @@ export async function dispatchUpdateUserFlagsAction ({ action, cache }: {
|
||||
})
|
||||
|
||||
if (!userEntry) {
|
||||
throw new Error('user not found')
|
||||
throw new MissingUserException()
|
||||
}
|
||||
|
||||
const oldFlags = parseInt(userEntry.flags, 10)
|
||||
|
||||
if (!Number.isSafeInteger(oldFlags)) {
|
||||
throw new Error()
|
||||
throw new IllegalStateException({ staticMessage: 'oldFlags is not a safe integer' })
|
||||
}
|
||||
|
||||
const newFlags = (oldFlags & ~action.modifiedBits) | action.newValues
|
||||
|
||||
+9
-8
@@ -17,6 +17,8 @@
|
||||
|
||||
import { UpdateUserLimitLoginCategory } from '../../../../action'
|
||||
import { Cache } from '../cache'
|
||||
import { ApplyActionException } from '../exception/index'
|
||||
import { MissingCategoryException, MissingUserException } from '../exception/missing-item'
|
||||
|
||||
export async function dispatchUpdateUserLimitLoginCategoryAction ({ action, cache, parentUserId }: {
|
||||
action: UpdateUserLimitLoginCategory
|
||||
@@ -26,21 +28,20 @@ export async function dispatchUpdateUserLimitLoginCategoryAction ({ action, cach
|
||||
const userEntry = await cache.database.user.findOne({
|
||||
where: {
|
||||
familyId: cache.familyId,
|
||||
userId: action.userId
|
||||
userId: action.userId,
|
||||
type: 'parent'
|
||||
},
|
||||
transaction: cache.transaction
|
||||
})
|
||||
|
||||
if (!userEntry) {
|
||||
throw new Error('user not found')
|
||||
}
|
||||
|
||||
if (userEntry.type !== 'parent') {
|
||||
throw new Error('user must be a parent')
|
||||
throw new MissingUserException()
|
||||
}
|
||||
|
||||
if (action.categoryId !== undefined && parentUserId !== action.userId) {
|
||||
throw new Error('only the user itself can add a limit')
|
||||
throw new ApplyActionException({
|
||||
staticMessage: 'only the parent user itself can add a limit login category'
|
||||
})
|
||||
}
|
||||
|
||||
await cache.database.userLimitLoginCategory.destroy({
|
||||
@@ -61,7 +62,7 @@ export async function dispatchUpdateUserLimitLoginCategoryAction ({ action, cach
|
||||
})
|
||||
|
||||
if (!categoryEntry) {
|
||||
throw new Error('category must exist')
|
||||
throw new MissingCategoryException()
|
||||
}
|
||||
|
||||
await cache.database.userLimitLoginCategory.create({
|
||||
|
||||
Reference in New Issue
Block a user