Initial commit

This commit is contained in:
Jonas L
2019-02-25 00:00:00 +00:00
commit 22c372e246
200 changed files with 27781 additions and 0 deletions
+51
View File
@@ -0,0 +1,51 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertNonEmptyListWithoutDuplicates } from '../util/list'
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class AddCategoryAppsAction extends ParentAction {
readonly categoryId: string
readonly packageNames: Array<string>
constructor ({ categoryId, packageNames }: {categoryId: string, packageNames: Array<string>}) {
super()
assertIdWithinFamily(categoryId)
assertNonEmptyListWithoutDuplicates(packageNames)
this.categoryId = categoryId
this.packageNames = packageNames
}
serialize = (): SerializedAddCategoryAppsAction => ({
type: 'ADD_CATEGORY_APPS',
categoryId: this.categoryId,
packageNames: this.packageNames
})
static parse = ({ categoryId, packageNames }: SerializedAddCategoryAppsAction) => (
new AddCategoryAppsAction({ categoryId, packageNames })
)
}
export interface SerializedAddCategoryAppsAction {
type: 'ADD_CATEGORY_APPS'
categoryId: string
packageNames: Array<string>
}
+48
View File
@@ -0,0 +1,48 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { InstalledApp, SerializedInstalledApp } from '../model/installedapp'
import { assertNonEmptyListWithoutDuplicates } from '../util/list'
import { AppLogicAction } from './basetypes'
export class AddInstalledAppsAction extends AppLogicAction {
readonly apps: Array<InstalledApp>
constructor ({ apps }: {apps: Array<InstalledApp>}) {
super()
assertNonEmptyListWithoutDuplicates(apps.map((app) => app.packageName))
this.apps = apps
}
serialize = (): SerializedAddInstalledAppsAction => ({
type: 'ADD_INSTALLED_APPS',
apps: this.apps.map((app) => app.serialize())
})
static parse = ({ apps }: SerializedAddInstalledAppsAction) => (
new AddInstalledAppsAction({
apps: apps.map((app) => InstalledApp.parse(app))
})
)
}
export interface SerializedAddInstalledAppsAction {
type: 'ADD_INSTALLED_APPS'
apps: Array<SerializedInstalledApp>
}
+79
View File
@@ -0,0 +1,79 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertIdWithinFamily } from '../util/token'
import { AppLogicAction } from './basetypes'
export class AddUsedTimeAction extends AppLogicAction {
readonly categoryId: string
readonly dayOfEpoch: number
readonly timeToAdd: number
readonly extraTimeToSubtract: number
constructor ({ categoryId, dayOfEpoch, timeToAdd, extraTimeToSubtract }: {
categoryId: string
dayOfEpoch: number
timeToAdd: number
extraTimeToSubtract: number
}) {
super()
assertIdWithinFamily(categoryId)
if (dayOfEpoch < 0 || (!Number.isSafeInteger(dayOfEpoch))) {
throw new Error('illegal dayOfEpoch')
}
if (timeToAdd < 0 || (!Number.isSafeInteger(timeToAdd))) {
throw new Error('illegal timeToAdd')
}
if (extraTimeToSubtract < 0 || (!Number.isSafeInteger(extraTimeToSubtract))) {
throw new Error('illegal extra time to subtract')
}
this.categoryId = categoryId
this.dayOfEpoch = dayOfEpoch
this.timeToAdd = timeToAdd
this.extraTimeToSubtract = extraTimeToSubtract
}
serialize = (): SerializedAddUsedTimeAction => ({
type: 'ADD_USED_TIME',
categoryId: this.categoryId,
day: this.dayOfEpoch,
timeToAdd: this.timeToAdd,
extraTimeToSubtract: this.extraTimeToSubtract
})
static parse = ({ categoryId, day, timeToAdd, extraTimeToSubtract }: SerializedAddUsedTimeAction) => (
new AddUsedTimeAction({
categoryId,
dayOfEpoch: day,
timeToAdd,
extraTimeToSubtract
})
)
}
export interface SerializedAddUsedTimeAction {
type: 'ADD_USED_TIME'
categoryId: string
day: number
timeToAdd: number
extraTimeToSubtract: number
}
+84
View File
@@ -0,0 +1,84 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertParentPasswordValid, ParentPassword } from '../api/schema'
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class AddUserAction extends ParentAction {
readonly userId: string
readonly name: string
readonly userType: 'parent' | 'child'
readonly password?: ParentPassword
readonly timeZone: string
constructor ({ userId, name, userType, password, timeZone }: {
userId: string
name: string
userType: 'parent' | 'child'
password?: ParentPassword
timeZone: string
}) {
super()
assertIdWithinFamily(userId)
this.userId = userId
this.name = name
this.userType = userType
this.password = password
this.timeZone = timeZone
if (userType === 'parent') {
if (!password) {
throw new Error('parent users must have got an password')
}
}
if (password) {
assertParentPasswordValid(password)
}
}
serialize = (): SerializedAddUserAction => ({
type: 'ADD_USER',
name: this.name,
userType: this.userType,
userId: this.userId,
password: this.password,
timeZone: this.timeZone
})
static parse = ({ name, userId, userType, password, timeZone }: SerializedAddUserAction) => (
new AddUserAction({
name,
userId,
userType,
password,
timeZone
})
)
}
export interface SerializedAddUserAction {
type: 'ADD_USER'
name: string
userType: 'parent' | 'child'
userId: string
password?: ParentPassword
timeZone: string
}
+26
View File
@@ -0,0 +1,26 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
export abstract class Action {
abstract serialize: () => object
}
export abstract class AppLogicAction extends Action {}
export abstract class ParentAction extends Action {}
export abstract class ChildAction extends Action {}
+126
View File
@@ -0,0 +1,126 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { createDecipheriv, createHash } from 'crypto'
import { assertIsHexString } from '../util/hexstring'
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class ChangeParentPasswordAction extends ParentAction {
readonly parentUserId: string
readonly newPasswordFirstHash: string
readonly newPasswordSecondSalt: string
readonly newPasswordSecondHashEncrypted: string
readonly integrity: string
constructor ({ parentUserId, newPasswordFirstHash, newPasswordSecondSalt, newPasswordSecondHashEncrypted, integrity }: {
parentUserId: string
newPasswordFirstHash: string
newPasswordSecondSalt: string
newPasswordSecondHashEncrypted: string
integrity: string
}) {
super()
assertIdWithinFamily(parentUserId)
if (
(!parentUserId) ||
(!newPasswordFirstHash) ||
(!newPasswordSecondSalt) ||
(!newPasswordSecondHashEncrypted) ||
(!integrity)
) {
throw new Error('missing required parameter for change parent password')
}
if (integrity.length !== 128) {
throw new Error('wrong length of integrity data')
}
assertIsHexString(newPasswordSecondHashEncrypted)
assertIsHexString(integrity)
this.parentUserId = parentUserId
this.newPasswordFirstHash = newPasswordFirstHash
this.newPasswordSecondSalt = newPasswordSecondSalt
this.newPasswordSecondHashEncrypted = newPasswordSecondHashEncrypted
this.integrity = integrity
}
serialize = (): SerializedChangeParentPasswordAction => ({
type: 'CHANGE_PARENT_PASSWORD',
userId: this.parentUserId,
hash: this.newPasswordFirstHash,
secondSalt: this.newPasswordSecondSalt,
secondHashEncrypted: this.newPasswordSecondHashEncrypted,
integrity: this.integrity
})
static parse = ({ userId, hash, secondSalt, secondHashEncrypted, integrity }: SerializedChangeParentPasswordAction) => (
new ChangeParentPasswordAction({
parentUserId: userId,
newPasswordFirstHash: hash,
newPasswordSecondSalt: secondSalt,
newPasswordSecondHashEncrypted: secondHashEncrypted,
integrity
})
)
assertIntegrityValid ({ oldPasswordSecondHash }: {oldPasswordSecondHash: string}) {
const integrityData = oldPasswordSecondHash +
this.parentUserId +
this.newPasswordFirstHash +
this.newPasswordSecondSalt +
this.newPasswordSecondHashEncrypted
const expected = createHash('sha512').update(integrityData).digest('hex')
if (expected !== this.integrity) {
throw new Error('invalid integrity for change parent password action')
}
}
decryptSecondHash ({ oldPasswordSecondHash }: {oldPasswordSecondHash: string}) {
if (this.newPasswordSecondHashEncrypted.length <= 70) {
throw new Error('wrong length of the new password')
}
const ivHex = this.newPasswordSecondHashEncrypted.substring(0, 32)
const salt = this.newPasswordSecondHashEncrypted.substring(32, 64)
const encryptedData = this.newPasswordSecondHashEncrypted.substring(64)
const keyData = oldPasswordSecondHash + salt
const key = createHash('sha512').update(keyData).digest().slice(0, 16)
const decipher = createDecipheriv('aes-128-ctr', key, Buffer.from(ivHex, 'hex'))
decipher.setAutoPadding(false)
const decryptedSecondHash = decipher.update(Buffer.from(encryptedData, 'hex')).toString() + decipher.final().toString()
return decryptedSecondHash
}
}
export interface SerializedChangeParentPasswordAction {
type: 'CHANGE_PARENT_PASSWORD'
userId: string
hash: string
secondSalt: string
secondHashEncrypted: string
integrity: string
}
+47
View File
@@ -0,0 +1,47 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertParentPasswordValid, ParentPassword } from '../api/schema'
import { ChildAction } from './basetypes'
export class ChildChangePasswordAction extends ChildAction {
readonly password: ParentPassword
constructor ({ password }: {
password: ParentPassword
}) {
super()
assertParentPasswordValid(password)
this.password = password
}
serialize = (): SerializedChildChangePasswordAction => ({
type: 'CHILD_CHANGE_PASSWORD',
password: this.password
})
static parse = ({ password }: SerializedChildChangePasswordAction) => (
new ChildChangePasswordAction({ password })
)
}
export interface SerializedChildChangePasswordAction {
type: 'CHILD_CHANGE_PASSWORD'
password: ParentPassword
}
+36
View File
@@ -0,0 +1,36 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { ChildAction } from './basetypes'
export class ChildSignInAction extends ChildAction {
constructor () {
super()
}
serialize = (): SerializedChildSignInAction => ({
type: 'CHILD_SIGN_IN'
})
static parse = (action: SerializedChildSignInAction) => (
new ChildSignInAction()
)
}
export interface SerializedChildSignInAction {
type: 'CHILD_SIGN_IN'
}
+54
View File
@@ -0,0 +1,54 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class CreateCategoryAction extends ParentAction {
readonly categoryId: string
readonly childId: string
readonly title: string
constructor ({ categoryId, childId, title }: {categoryId: string, childId: string, title: string}) {
super()
assertIdWithinFamily(categoryId)
assertIdWithinFamily(childId)
this.categoryId = categoryId
this.childId = childId
this.title = title
}
serialize = (): SerializedCreateCategoryAction => ({
type: 'CREATE_CATEGORY',
childId: this.childId,
categoryId: this.categoryId,
title: this.title
})
static parse = ({ childId, categoryId, title }: SerializedCreateCategoryAction) => (
new CreateCategoryAction({ childId, categoryId, title })
)
}
export interface SerializedCreateCategoryAction {
type: 'CREATE_CATEGORY'
childId: string
categoryId: string
title: string
}
+45
View File
@@ -0,0 +1,45 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { SerializedTimeLimitRule, TimelimitRule } from '../model/timelimitrule'
import { ParentAction } from './basetypes'
export class CreateTimeLimitRuleAction extends ParentAction {
rule: TimelimitRule
constructor ({ rule }: {rule: TimelimitRule}) {
super()
this.rule = rule
}
serialize = (): SerializedCreateTimelimtRuleAction => ({
type: 'CREATE_TIMELIMIT_RULE',
rule: this.rule.serialize()
})
static parse = ({ rule }: SerializedCreateTimelimtRuleAction) => (
new CreateTimeLimitRuleAction({
rule: TimelimitRule.parse(rule)
})
)
}
export interface SerializedCreateTimelimtRuleAction {
type: 'CREATE_TIMELIMIT_RULE'
rule: SerializedTimeLimitRule
}
+45
View File
@@ -0,0 +1,45 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class DeleteCategoryAction extends ParentAction {
readonly categoryId: string
constructor ({ categoryId }: {categoryId: string}) {
super()
assertIdWithinFamily(categoryId)
this.categoryId = categoryId
}
serialize = (): SerializedDeleteCategoryAction => ({
type: 'DELETE_CATEGORY',
categoryId: this.categoryId
})
static parse = ({ categoryId }: SerializedDeleteCategoryAction) => (
new DeleteCategoryAction({ categoryId })
)
}
export interface SerializedDeleteCategoryAction {
type: 'DELETE_CATEGORY'
categoryId: string
}
+45
View File
@@ -0,0 +1,45 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class DeleteTimeLimitRuleAction extends ParentAction {
readonly ruleId: string
constructor ({ ruleId }: {ruleId: string}) {
super()
assertIdWithinFamily(ruleId)
this.ruleId = ruleId
}
serialize = (): SerializedDeleteTimeLimitRuleAction => ({
type: 'DELETE_TIMELIMIT_RULE',
ruleId: this.ruleId
})
static parse = ({ ruleId }: SerializedDeleteTimeLimitRuleAction) => (
new DeleteTimeLimitRuleAction({ ruleId })
)
}
export interface SerializedDeleteTimeLimitRuleAction {
type: 'DELETE_TIMELIMIT_RULE'
ruleId: string
}
+95
View File
@@ -0,0 +1,95 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class IgnoreManipulationAction extends ParentAction {
readonly deviceId: string
readonly ignoreDeviceAdminManipulation: boolean
readonly ignoreDeviceAdminManipulationAttempt: boolean
readonly ignoreAppDowngrade: boolean
readonly ignoreNotificationAccessManipulation: boolean
readonly ignoreUsageStatsAccessManipulation: boolean
readonly ignoreDidReboot: boolean
readonly ignoreHadManipulation: boolean
constructor ({
deviceId, ignoreDeviceAdminManipulation, ignoreDeviceAdminManipulationAttempt,
ignoreAppDowngrade, ignoreNotificationAccessManipulation, ignoreUsageStatsAccessManipulation,
ignoreDidReboot, ignoreHadManipulation
}: {
deviceId: string
ignoreDeviceAdminManipulation: boolean
ignoreDeviceAdminManipulationAttempt: boolean
ignoreAppDowngrade: boolean
ignoreNotificationAccessManipulation: boolean
ignoreUsageStatsAccessManipulation: boolean
ignoreDidReboot: boolean
ignoreHadManipulation: boolean
}) {
super()
assertIdWithinFamily(deviceId)
this.deviceId = deviceId
this.ignoreDeviceAdminManipulation = ignoreDeviceAdminManipulation
this.ignoreDeviceAdminManipulationAttempt = ignoreDeviceAdminManipulationAttempt
this.ignoreAppDowngrade = ignoreAppDowngrade
this.ignoreNotificationAccessManipulation = ignoreNotificationAccessManipulation
this.ignoreUsageStatsAccessManipulation = ignoreUsageStatsAccessManipulation
this.ignoreDidReboot = ignoreDidReboot
this.ignoreHadManipulation = ignoreHadManipulation
}
serialize = (): SerializedIgnoreManipulationAction => ({
type: 'IGNORE_MANIPULATION',
deviceId: this.deviceId,
admin: this.ignoreDeviceAdminManipulation,
adminA: this.ignoreDeviceAdminManipulationAttempt,
downgrade: this.ignoreAppDowngrade,
notification: this.ignoreNotificationAccessManipulation,
usageStats: this.ignoreUsageStatsAccessManipulation,
hadManipulation: this.ignoreHadManipulation
})
static parse = ({ deviceId, admin, adminA, downgrade, notification, usageStats, reboot, hadManipulation }: SerializedIgnoreManipulationAction) => (
new IgnoreManipulationAction({
deviceId,
ignoreDeviceAdminManipulation: admin,
ignoreDeviceAdminManipulationAttempt: adminA,
ignoreAppDowngrade: downgrade,
ignoreUsageStatsAccessManipulation: usageStats,
ignoreNotificationAccessManipulation: notification,
ignoreDidReboot: !!reboot,
ignoreHadManipulation: hadManipulation
})
)
}
export interface SerializedIgnoreManipulationAction {
type: 'IGNORE_MANIPULATION'
deviceId: string
admin: boolean
adminA: boolean
downgrade: boolean
notification: boolean
usageStats: boolean
hadManipulation: boolean
// was added at a later version
reboot?: boolean
}
+53
View File
@@ -0,0 +1,53 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class IncrementCategoryExtraTimeAction extends ParentAction {
readonly categoryId: string
readonly addedExtraTime: number
constructor ({ categoryId, addedExtraTime }: {categoryId: string, addedExtraTime: number}) {
super()
assertIdWithinFamily(categoryId)
if (addedExtraTime <= 0 || (!Number.isSafeInteger(addedExtraTime))) {
throw new Error('must add some extra time with IncrementCategoryExtraTimeAction')
}
this.categoryId = categoryId
this.addedExtraTime = addedExtraTime
}
serialize = (): SerializedIncrementCategoryExtraTimeAction => ({
type: 'INCREMENT_CATEGORY_EXTRATIME',
categoryId: this.categoryId,
addedExtraTime: this.addedExtraTime
})
static parse = ({ categoryId, addedExtraTime }: SerializedIncrementCategoryExtraTimeAction) => (
new IncrementCategoryExtraTimeAction({ categoryId, addedExtraTime })
)
}
export interface SerializedIncrementCategoryExtraTimeAction {
type: 'INCREMENT_CATEGORY_EXTRATIME'
categoryId: string
addedExtraTime: number
}
+59
View File
@@ -0,0 +1,59 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
export { AppLogicAction, ChildAction, ParentAction } from './basetypes'
export { AddCategoryAppsAction } from './addcategoryapps'
export { AddUserAction } from './adduser'
export { AddInstalledAppsAction } from './addinstalledapps'
export { AddUsedTimeAction } from './addusedtime'
export { ChangeParentPasswordAction } from './changeparentpassword'
export { ChildChangePasswordAction } from './childchangepassword'
export { ChildSignInAction } from './childsignin'
export { CreateCategoryAction } from './createcategory'
export { CreateTimeLimitRuleAction } from './createtimelimitrule'
export { DeleteCategoryAction } from './deletecategory'
export { DeleteTimeLimitRuleAction } from './deletetimelimitrule'
export { IgnoreManipulationAction } from './ignoremanipulation'
export { IncrementCategoryExtraTimeAction } from './incrementcategoryextratime'
export { RemoveCategoryAppsAction } from './removecategoryapps'
export { RemoveInstalledAppsAction } from './removeinstalledapps'
export { RemoveUserAction } from './removeuser'
export { RenameChildAction } from './renamechild'
export { SetCategoryExtraTimeAction } from './setcategoryextratime'
export { SetCategoryForUnassignedAppsAction } from './setcategoryforunassignedapps'
export { SetChildPasswordAction } from './setchildpassword'
export { SetConsiderRebootManipulationAction } from './setconsiderrebootmanipulation'
export { SetDeviceDefaultUserAction } from './setdevicedefaultuser'
export { SetDeviceDefaultUserTimeoutAction } from './setdevicedefaultusertimeout'
export { SetDeviceUserAction } from './setdeviceuser'
export { SetKeepSignedInAction } from './setkeepsignedin'
export { SetParentCategoryAction } from './setparentcategory'
export { SetRelaxPrimaryDeviceAction } from './setrelaxprimarydevice'
export { SetSendDeviceConnected } from './setsenddeviceconnected'
export { SetUserDisableLimitsUntilAction } from './setuserdisablelimitsuntil'
export { SetUserTimezoneAction } from './setusertimezone'
export { SignOutAtDeviceAction } from './signoutatdevice'
export { TriedDisablingDeviceAdminAction } from './trieddisablingdeviceadmin'
export { UpdateCategoryBlockedTimesAction } from './updatecategoryblockedtimes'
export { UpdateCategoryTemporarilyBlockedAction } from './updatecategorytemporarilyblocked'
export { UpdateCategoryTitleAction } from './updatecategorytitle'
export { UpdateDeviceNameAction } from './updatedevicename'
export { UpdateDeviceStatusAction } from './updatedevicestatus'
export { UpdateNetworkTimeVerificationAction } from './updatenetworktimeverification'
export { UpdateParentNotificationFlagsAction } from './updateparentnotificationflags'
export { UpdateTimelimitRuleAction } from './updatetimelimitrule'
+51
View File
@@ -0,0 +1,51 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertNonEmptyListWithoutDuplicates } from '../util/list'
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class RemoveCategoryAppsAction extends ParentAction {
readonly categoryId: string
readonly packageNames: Array<string>
constructor ({ categoryId, packageNames }: {categoryId: string, packageNames: Array<string>}) {
super()
assertIdWithinFamily(categoryId)
assertNonEmptyListWithoutDuplicates(packageNames)
this.categoryId = categoryId
this.packageNames = packageNames
}
serialize = (): SerializedRemoveCategoryAppsAction => ({
type: 'REMOVE_CATEGORY_APPS',
categoryId: this.categoryId,
packageNames: this.packageNames
})
static parse = ({ categoryId, packageNames }: SerializedRemoveCategoryAppsAction) => (
new RemoveCategoryAppsAction({ categoryId, packageNames })
)
}
export interface SerializedRemoveCategoryAppsAction {
type: 'REMOVE_CATEGORY_APPS'
categoryId: string
packageNames: Array<string>
}
+45
View File
@@ -0,0 +1,45 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertNonEmptyListWithoutDuplicates } from '../util/list'
import { AppLogicAction } from './basetypes'
export class RemoveInstalledAppsAction extends AppLogicAction {
readonly packageNames: Array<string>
constructor ({ packageNames }: {packageNames: Array<string>}) {
super()
assertNonEmptyListWithoutDuplicates(packageNames)
this.packageNames = packageNames
}
serialize = (): SerializedRemoveInstalledAppsAction => ({
type: 'REMOVE_INSTALLED_APPS',
packageNames: this.packageNames
})
static parse = ({ packageNames }: SerializedRemoveInstalledAppsAction) => (
new RemoveInstalledAppsAction({ packageNames })
)
}
export interface SerializedRemoveInstalledAppsAction {
type: 'REMOVE_INSTALLED_APPS'
packageNames: Array<string>
}
+55
View File
@@ -0,0 +1,55 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class RemoveUserAction extends ParentAction {
readonly userId: string
// required for deleting parent users
// parent users can only be removed by other parent users
// this should be the value of sha512(userId + secondPasswordHash + 'remove').substring(0, 16)
readonly authentication?: string
constructor ({ userId, authentication }: {
userId: string
authentication?: string
}) {
super()
assertIdWithinFamily(userId)
this.userId = userId
this.authentication = authentication
}
serialize = (): SerializedRemoveUserAction => ({
type: 'REMOVE_USER',
userId: this.userId,
authentication: this.authentication
})
static parse = ({ userId, authentication }: SerializedRemoveUserAction) => (
new RemoveUserAction({ userId, authentication })
)
}
export interface SerializedRemoveUserAction {
type: 'REMOVE_USER'
userId: string
authentication?: string
}
+56
View File
@@ -0,0 +1,56 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class RenameChildAction extends ParentAction {
readonly childId: string
readonly newName: string
constructor ({ childId, newName }: {
childId: string
newName: string
}) {
super()
assertIdWithinFamily(childId)
if (newName === '') {
throw new Error('new name must not be empty')
}
this.childId = childId
this.newName = newName
}
serialize = (): SerializedRenameChildAction => ({
type: 'RENAME_CHILD',
childId: this.childId,
newName: this.newName
})
static parse = ({ childId, newName }: SerializedRenameChildAction) => (
new RenameChildAction({ childId, newName })
)
}
export interface SerializedRenameChildAction {
type: 'RENAME_CHILD'
childId: string
newName: string
}
@@ -0,0 +1,50 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { AddInstalledAppsAction, SerializedAddInstalledAppsAction } from '../addinstalledapps'
import { AddUsedTimeAction, SerializedAddUsedTimeAction } from '../addusedtime'
import { AppLogicAction } from '../basetypes'
import { RemoveInstalledAppsAction, SerializedRemoveInstalledAppsAction } from '../removeinstalledapps'
import { SerializedSignOutAtDeviceAction, SignOutAtDeviceAction } from '../signoutatdevice'
import { SerialiezdTriedDisablingDeviceAdminAction, TriedDisablingDeviceAdminAction } from '../trieddisablingdeviceadmin'
import { SerializedUpdateDeviceStatusAction, UpdateDeviceStatusAction } from '../updatedevicestatus'
export type SerializedAppLogicAction =
SerializedAddInstalledAppsAction |
SerializedAddUsedTimeAction |
SerializedRemoveInstalledAppsAction |
SerializedSignOutAtDeviceAction |
SerialiezdTriedDisablingDeviceAdminAction |
SerializedUpdateDeviceStatusAction
export const parseAppLogicAction = (serialized: SerializedAppLogicAction): AppLogicAction => {
if (serialized.type === 'ADD_USED_TIME') {
return AddUsedTimeAction.parse(serialized)
} else if (serialized.type === 'ADD_INSTALLED_APPS') {
return AddInstalledAppsAction.parse(serialized)
} else if (serialized.type === 'REMOVE_INSTALLED_APPS') {
return RemoveInstalledAppsAction.parse(serialized)
} else if (serialized.type === 'SIGN_OUT_AT_DEVICE') {
return SignOutAtDeviceAction.parse(serialized)
} else if (serialized.type === 'TRIED_DISABLING_DEVICE_ADMIN') {
return new TriedDisablingDeviceAdminAction()
} else if (serialized.type === 'UPDATE_DEVICE_STATUS') {
return UpdateDeviceStatusAction.parse(serialized)
} else {
throw new Error('illegal state: unsupported type at parseAppLogicAction')
}
}
+31
View File
@@ -0,0 +1,31 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { ChildChangePasswordAction, SerializedChildChangePasswordAction } from '../childchangepassword'
import { ChildSignInAction, SerializedChildSignInAction } from '../childsignin'
export type SerializedChildAction = SerializedChildChangePasswordAction | SerializedChildSignInAction
export const parseChildAction = (serialized: SerializedChildAction) => {
if (serialized.type === 'CHILD_CHANGE_PASSWORD') {
return ChildChangePasswordAction.parse(serialized)
} else if (serialized.type === 'CHILD_SIGN_IN') {
return ChildSignInAction.parse(serialized)
} else {
throw new Error('illegal state: unsupported type at parseChildAction')
}
}
+20
View File
@@ -0,0 +1,20 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
export { parseAppLogicAction, SerializedAppLogicAction } from './applogicaction'
export { parseChildAction, SerializedChildAction } from './childaction'
export { parseParentAction, SerializedParentAction } from './parentaction'
+154
View File
@@ -0,0 +1,154 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { AddCategoryAppsAction, SerializedAddCategoryAppsAction } from '../addcategoryapps'
import { AddUserAction, SerializedAddUserAction } from '../adduser'
import { ParentAction } from '../basetypes'
import { ChangeParentPasswordAction, SerializedChangeParentPasswordAction } from '../changeparentpassword'
import { CreateCategoryAction, SerializedCreateCategoryAction } from '../createcategory'
import { CreateTimeLimitRuleAction, SerializedCreateTimelimtRuleAction } from '../createtimelimitrule'
import { DeleteCategoryAction, SerializedDeleteCategoryAction } from '../deletecategory'
import { DeleteTimeLimitRuleAction, SerializedDeleteTimeLimitRuleAction } from '../deletetimelimitrule'
import { IgnoreManipulationAction, SerializedIgnoreManipulationAction } from '../ignoremanipulation'
import { IncrementCategoryExtraTimeAction, SerializedIncrementCategoryExtraTimeAction } from '../incrementcategoryextratime'
import { RemoveCategoryAppsAction, SerializedRemoveCategoryAppsAction } from '../removecategoryapps'
import { RemoveUserAction, SerializedRemoveUserAction } from '../removeuser'
import { RenameChildAction, SerializedRenameChildAction } from '../renamechild'
import { SerializedSetCategoryExtraTimeAction, SetCategoryExtraTimeAction } from '../setcategoryextratime'
import { SerializedSetCategoryForUnassignedAppsAction, SetCategoryForUnassignedAppsAction } from '../setcategoryforunassignedapps'
import { SerializedSetChildPasswordAction, SetChildPasswordAction } from '../setchildpassword'
import { SerializedSetConsiderRebootManipulationAction, SetConsiderRebootManipulationAction } from '../setconsiderrebootmanipulation'
import { SerializedSetDeviceDefaultUserAction, SetDeviceDefaultUserAction } from '../setdevicedefaultuser'
import { SerializedSetDeviceDefaultUserTimeoutAction, SetDeviceDefaultUserTimeoutAction } from '../setdevicedefaultusertimeout'
import { SerializedSetDeviceUserAction, SetDeviceUserAction } from '../setdeviceuser'
import { SerializedSetKeepSignedInAction, SetKeepSignedInAction } from '../setkeepsignedin'
import { SerializedSetParentCategoryAction, SetParentCategoryAction } from '../setparentcategory'
import { SerializedSetRelaxPrimaryDeviceAction, SetRelaxPrimaryDeviceAction } from '../setrelaxprimarydevice'
import { SerializedSetSendDeviceConnected, SetSendDeviceConnected } from '../setsenddeviceconnected'
import { SerializedSetUserDisableLimitsUntilAction, SetUserDisableLimitsUntilAction } from '../setuserdisablelimitsuntil'
import { SerializedSetUserTimezoneAction, SetUserTimezoneAction } from '../setusertimezone'
import { SerializedUpdateCategoryBlockedTimesAction, UpdateCategoryBlockedTimesAction } from '../updatecategoryblockedtimes'
import { SerializedUpdateCategoryTemporarilyBlockedAction, UpdateCategoryTemporarilyBlockedAction } from '../updatecategorytemporarilyblocked'
import { SerializedUpdateCategoryTitleAction, UpdateCategoryTitleAction } from '../updatecategorytitle'
import { SerializedUpdateDeviceNameAction, UpdateDeviceNameAction } from '../updatedevicename'
import { SerialiizedUpdateNetworkTimeVerificationAction, UpdateNetworkTimeVerificationAction } from '../updatenetworktimeverification'
import { SerializedUpdateParentNotificationFlagsAction, UpdateParentNotificationFlagsAction } from '../updateparentnotificationflags'
import { SerializedUpdateTimelimitRuleAction, UpdateTimelimitRuleAction } from '../updatetimelimitrule'
export type SerializedParentAction =
SerializedAddCategoryAppsAction |
SerializedAddUserAction |
SerializedChangeParentPasswordAction |
SerializedCreateCategoryAction |
SerializedCreateTimelimtRuleAction |
SerializedDeleteCategoryAction |
SerializedDeleteTimeLimitRuleAction |
SerializedIgnoreManipulationAction |
SerializedIncrementCategoryExtraTimeAction |
SerializedRemoveCategoryAppsAction |
SerializedRemoveUserAction |
SerializedRenameChildAction |
SerializedSetCategoryForUnassignedAppsAction |
SerializedSetChildPasswordAction |
SerializedSetConsiderRebootManipulationAction |
SerializedSetDeviceDefaultUserAction |
SerializedSetDeviceDefaultUserTimeoutAction |
SerializedSetCategoryExtraTimeAction |
SerializedSetDeviceUserAction |
SerializedSetKeepSignedInAction |
SerializedSetParentCategoryAction |
SerializedSetRelaxPrimaryDeviceAction |
SerializedSetSendDeviceConnected |
SerializedSetUserDisableLimitsUntilAction |
SerializedSetUserTimezoneAction |
SerializedUpdateCategoryBlockedTimesAction |
SerializedUpdateCategoryTemporarilyBlockedAction |
SerializedUpdateCategoryTitleAction |
SerializedUpdateDeviceNameAction |
SerialiizedUpdateNetworkTimeVerificationAction |
SerializedUpdateParentNotificationFlagsAction |
SerializedUpdateTimelimitRuleAction
export const parseParentAction = (action: SerializedParentAction): ParentAction => {
if (action.type === 'ADD_CATEGORY_APPS') {
return AddCategoryAppsAction.parse(action)
} else if (action.type === 'ADD_USER') {
return AddUserAction.parse(action)
} else if (action.type === 'CHANGE_PARENT_PASSWORD') {
return ChangeParentPasswordAction.parse(action)
} else if (action.type === 'CREATE_CATEGORY') {
return CreateCategoryAction.parse(action)
} else if (action.type === 'CREATE_TIMELIMIT_RULE') {
return CreateTimeLimitRuleAction.parse(action)
} else if (action.type === 'DELETE_CATEGORY') {
return DeleteCategoryAction.parse(action)
} else if (action.type === 'DELETE_TIMELIMIT_RULE') {
return DeleteTimeLimitRuleAction.parse(action)
} else if (action.type === 'IGNORE_MANIPULATION') {
return IgnoreManipulationAction.parse(action)
} else if (action.type === 'INCREMENT_CATEGORY_EXTRATIME') {
return IncrementCategoryExtraTimeAction.parse(action)
} else if (action.type === 'REMOVE_CATEGORY_APPS') {
return RemoveCategoryAppsAction.parse(action)
} else if (action.type === 'REMOVE_USER') {
return RemoveUserAction.parse(action)
} else if (action.type === 'RENAME_CHILD') {
return RenameChildAction.parse(action)
} else if (action.type === 'SET_CATEGORY_EXTRA_TIME') {
return SetCategoryExtraTimeAction.parse(action)
} else if (action.type === 'SET_CATEGORY_FOR_UNASSIGNED_APPS') {
return SetCategoryForUnassignedAppsAction.parse(action)
} else if (action.type === 'SET_CHILD_PASSWORD') {
return SetChildPasswordAction.parse(action)
} else if (action.type === 'SET_CONSIDER_REBOOT_MANIPULATION') {
return SetConsiderRebootManipulationAction.parse(action)
} else if (action.type === 'SET_DEVICE_DEFAULT_USER') {
return SetDeviceDefaultUserAction.parse(action)
} else if (action.type === 'SET_DEVICE_DEFAULT_USER_TIMEOUT') {
return SetDeviceDefaultUserTimeoutAction.parse(action)
} else if (action.type === 'SET_DEVICE_USER') {
return SetDeviceUserAction.parse(action)
} else if (action.type === 'SET_KEEP_SIGNED_IN') {
return SetKeepSignedInAction.parse(action)
} else if (action.type === 'SET_PARENT_CATEGORY') {
return SetParentCategoryAction.parse(action)
} else if (action.type === 'SET_RELAX_PRIMARY_DEVICE') {
return SetRelaxPrimaryDeviceAction.parse(action)
} else if (action.type === 'SET_SEND_DEVICE_CONNECTED') {
return SetSendDeviceConnected.parse(action)
} else if (action.type === 'SET_USER_DISABLE_LIMITS_UNTIL') {
return SetUserDisableLimitsUntilAction.parse(action)
} else if (action.type === 'SET_USER_TIMEZONE') {
return SetUserTimezoneAction.parse(action)
} else if (action.type === 'UPDATE_CATEGORY_BLOCKED_TIMES') {
return UpdateCategoryBlockedTimesAction.parse(action)
} else if (action.type === 'UPDATE_CATEGORY_TITLE') {
return UpdateCategoryTitleAction.parse(action)
} else if (action.type === 'UPDATE_CATEGORY_TEMPORARILY_BLOCKED') {
return UpdateCategoryTemporarilyBlockedAction.parse(action)
} else if (action.type === 'UPDATE_DEVICE_NAME') {
return UpdateDeviceNameAction.parse(action)
} else if (action.type === 'UPDATE_NETWORK_TIME_VERIFICATION') {
return UpdateNetworkTimeVerificationAction.parse(action)
} else if (action.type === 'UPDATE_PARENT_NOTIFICATION_FLAGS') {
return UpdateParentNotificationFlagsAction.parse(action)
} else if (action.type === 'UPDATE_TIMELIMIT_RULE') {
return UpdateTimelimitRuleAction.parse(action)
} else {
throw new Error('illegal state: invalid type for action at parseParentAction')
}
}
+53
View File
@@ -0,0 +1,53 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class SetCategoryExtraTimeAction extends ParentAction {
readonly categoryId: string
readonly newExtraTime: number
constructor ({ categoryId, newExtraTime }: {categoryId: string, newExtraTime: number}) {
super()
assertIdWithinFamily(categoryId)
if (newExtraTime < 0 || (!Number.isSafeInteger(newExtraTime))) {
throw Error('newExtraTime must be >= 0')
}
this.categoryId = categoryId
this.newExtraTime = newExtraTime
}
serialize = (): SerializedSetCategoryExtraTimeAction => ({
type: 'SET_CATEGORY_EXTRA_TIME',
categoryId: this.categoryId,
newExtraTime: this.newExtraTime
})
static parse = ({ categoryId, newExtraTime }: SerializedSetCategoryExtraTimeAction) => (
new SetCategoryExtraTimeAction({ categoryId, newExtraTime })
)
}
export interface SerializedSetCategoryExtraTimeAction {
type: 'SET_CATEGORY_EXTRA_TIME'
categoryId: string
newExtraTime: number
}
@@ -0,0 +1,56 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class SetCategoryForUnassignedAppsAction extends ParentAction {
readonly childId: string
readonly categoryId: string
constructor ({ childId, categoryId }: {
childId: string
categoryId: string
}) {
super()
assertIdWithinFamily(childId)
if (categoryId !== '') {
assertIdWithinFamily(categoryId)
}
this.childId = childId
this.categoryId = categoryId
}
serialize = (): SerializedSetCategoryForUnassignedAppsAction => ({
type: 'SET_CATEGORY_FOR_UNASSIGNED_APPS',
childId: this.childId,
categoryId: this.categoryId
})
static parse = ({ childId, categoryId }: SerializedSetCategoryForUnassignedAppsAction) => (
new SetCategoryForUnassignedAppsAction({ childId, categoryId })
)
}
export interface SerializedSetCategoryForUnassignedAppsAction {
type: 'SET_CATEGORY_FOR_UNASSIGNED_APPS'
childId: string
categoryId: string
}
+57
View File
@@ -0,0 +1,57 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertParentPasswordValid, ParentPassword } from '../api/schema'
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class SetChildPasswordAction extends ParentAction {
readonly childUserId: string
readonly newPassword: ParentPassword
constructor ({ childUserId, newPassword }: {
childUserId: string
newPassword: ParentPassword
}) {
super()
assertIdWithinFamily(childUserId)
assertParentPasswordValid(newPassword)
this.childUserId = childUserId
this.newPassword = newPassword
}
serialize = (): SerializedSetChildPasswordAction => ({
type: 'SET_CHILD_PASSWORD',
childId: this.childUserId,
newPassword: this.newPassword
})
static parse = ({ childId, newPassword }: SerializedSetChildPasswordAction) => (
new SetChildPasswordAction({
childUserId: childId,
newPassword
})
)
}
export interface SerializedSetChildPasswordAction {
type: 'SET_CHILD_PASSWORD'
childId: string
newPassword: ParentPassword
}
@@ -0,0 +1,49 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class SetConsiderRebootManipulationAction extends ParentAction {
readonly deviceId: string
readonly enable: boolean
constructor ({ deviceId, enable }: {deviceId: string, enable: boolean}) {
super()
assertIdWithinFamily(deviceId)
this.deviceId = deviceId
this.enable = enable
}
serialize = (): SerializedSetConsiderRebootManipulationAction => ({
type: 'SET_CONSIDER_REBOOT_MANIPULATION',
deviceId: this.deviceId,
enable: this.enable
})
static parse = ({ deviceId, enable }: SerializedSetConsiderRebootManipulationAction) => (
new SetConsiderRebootManipulationAction({ deviceId, enable })
)
}
export interface SerializedSetConsiderRebootManipulationAction {
type: 'SET_CONSIDER_REBOOT_MANIPULATION'
deviceId: string
enable: boolean
}
+56
View File
@@ -0,0 +1,56 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class SetDeviceDefaultUserAction extends ParentAction {
readonly deviceId: string
readonly defaultUserId: string
constructor ({ deviceId, defaultUserId }: {
deviceId: string
defaultUserId: string
}) {
super()
assertIdWithinFamily(deviceId)
if (defaultUserId !== '') {
assertIdWithinFamily(defaultUserId)
}
this.deviceId = deviceId
this.defaultUserId = defaultUserId
}
serialize = (): SerializedSetDeviceDefaultUserAction => ({
type: 'SET_DEVICE_DEFAULT_USER',
deviceId: this.deviceId,
defaultUserId: this.defaultUserId
})
static parse = ({ deviceId, defaultUserId }: SerializedSetDeviceDefaultUserAction) => (
new SetDeviceDefaultUserAction({ deviceId, defaultUserId })
)
}
export interface SerializedSetDeviceDefaultUserAction {
type: 'SET_DEVICE_DEFAULT_USER'
deviceId: string
defaultUserId: string
}
+56
View File
@@ -0,0 +1,56 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class SetDeviceDefaultUserTimeoutAction extends ParentAction {
readonly deviceId: string
readonly timeout: number
constructor ({ deviceId, timeout }: {
deviceId: string
timeout: number
}) {
super()
assertIdWithinFamily(deviceId)
if ((!Number.isInteger(timeout)) || (timeout < 0)) {
throw new Error('timeout must be a non-negative integer')
}
this.deviceId = deviceId
this.timeout = timeout
}
serialize = (): SerializedSetDeviceDefaultUserTimeoutAction => ({
type: 'SET_DEVICE_DEFAULT_USER_TIMEOUT',
deviceId: this.deviceId,
timeout: this.timeout
})
static parse = ({ deviceId, timeout }: SerializedSetDeviceDefaultUserTimeoutAction) => (
new SetDeviceDefaultUserTimeoutAction({ deviceId, timeout })
)
}
export interface SerializedSetDeviceDefaultUserTimeoutAction {
type: 'SET_DEVICE_DEFAULT_USER_TIMEOUT'
deviceId: string
timeout: number
}
+56
View File
@@ -0,0 +1,56 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class SetDeviceUserAction extends ParentAction {
readonly deviceId: string
readonly userId: string // user id can be ""
constructor ({ deviceId, userId }: {
deviceId: string
userId: string
}) {
super()
assertIdWithinFamily(deviceId)
if (userId !== '') {
assertIdWithinFamily(userId)
}
this.deviceId = deviceId
this.userId = userId
}
serialize = (): SerializedSetDeviceUserAction => ({
type: 'SET_DEVICE_USER',
deviceId: this.deviceId,
userId: this.userId
})
static parse = ({ deviceId, userId }: SerializedSetDeviceUserAction) => (
new SetDeviceUserAction({ deviceId, userId })
)
}
export interface SerializedSetDeviceUserAction {
type: 'SET_DEVICE_USER'
deviceId: string
userId: string
}
+55
View File
@@ -0,0 +1,55 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class SetKeepSignedInAction extends ParentAction {
readonly deviceId: string
readonly keepSignedIn: boolean
constructor ({ deviceId, keepSignedIn }: {
deviceId: string
keepSignedIn: boolean
}) {
super()
assertIdWithinFamily(deviceId)
this.deviceId = deviceId
this.keepSignedIn = keepSignedIn
}
serialize = (): SerializedSetKeepSignedInAction => ({
type: 'SET_KEEP_SIGNED_IN',
deviceId: this.deviceId,
keepSignedIn: this.keepSignedIn
})
static parse = ({ deviceId, keepSignedIn }: SerializedSetKeepSignedInAction) => (
new SetKeepSignedInAction({
deviceId,
keepSignedIn
})
)
}
export interface SerializedSetKeepSignedInAction {
type: 'SET_KEEP_SIGNED_IN'
deviceId: string
keepSignedIn: boolean
}
+59
View File
@@ -0,0 +1,59 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class SetParentCategoryAction extends ParentAction {
readonly categoryId: string
readonly parentCategory: string
constructor ({ categoryId, parentCategory }: {
categoryId: string
parentCategory: string
}) {
super()
assertIdWithinFamily(categoryId)
if (parentCategory !== '') {
assertIdWithinFamily(parentCategory)
}
this.categoryId = categoryId
this.parentCategory = parentCategory
}
serialize = (): SerializedSetParentCategoryAction => ({
type: 'SET_PARENT_CATEGORY',
categoryId: this.categoryId,
parentCategory: this.parentCategory
})
static parse = ({ categoryId, parentCategory }: SerializedSetParentCategoryAction) => (
new SetParentCategoryAction({
categoryId,
parentCategory
})
)
}
export interface SerializedSetParentCategoryAction {
type: 'SET_PARENT_CATEGORY'
categoryId: string
parentCategory: string
}
+52
View File
@@ -0,0 +1,52 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class SetRelaxPrimaryDeviceAction extends ParentAction {
readonly userId: string
readonly relax: boolean
constructor ({ userId, relax }: {
userId: string
relax: boolean
}) {
super()
assertIdWithinFamily(userId)
this.userId = userId
this.relax = relax
}
serialize = (): SerializedSetRelaxPrimaryDeviceAction => ({
type: 'SET_RELAX_PRIMARY_DEVICE',
userId: this.userId,
relax: this.relax
})
static parse = ({ userId, relax }: SerializedSetRelaxPrimaryDeviceAction) => (
new SetRelaxPrimaryDeviceAction({ userId, relax })
)
}
export interface SerializedSetRelaxPrimaryDeviceAction {
type: 'SET_RELAX_PRIMARY_DEVICE'
userId: string
relax: boolean
}
+55
View File
@@ -0,0 +1,55 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class SetSendDeviceConnected extends ParentAction {
readonly deviceId: string
readonly enable: boolean
constructor ({ deviceId, enable }: {
deviceId: string
enable: boolean
}) {
super()
assertIdWithinFamily(deviceId)
this.deviceId = deviceId
this.enable = enable
}
serialize = (): SerializedSetSendDeviceConnected => ({
type: 'SET_SEND_DEVICE_CONNECTED',
deviceId: this.deviceId,
enable: this.enable
})
static parse = ({ deviceId, enable }: SerializedSetSendDeviceConnected) => (
new SetSendDeviceConnected({
deviceId,
enable
})
)
}
export interface SerializedSetSendDeviceConnected {
type: 'SET_SEND_DEVICE_CONNECTED'
deviceId: string
enable: boolean
}
+59
View File
@@ -0,0 +1,59 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class SetUserDisableLimitsUntilAction extends ParentAction {
readonly childId: string
readonly timestamp: number
constructor ({ childId, timestamp }: {
childId: string
timestamp: number
}) {
super()
assertIdWithinFamily(childId)
if (timestamp < 0 || (!Number.isSafeInteger(timestamp))) {
throw new Error('timestamp for set user disabe limits until must be >= 0')
}
this.childId = childId
this.timestamp = timestamp
}
serialize = (): SerializedSetUserDisableLimitsUntilAction => ({
type: 'SET_USER_DISABLE_LIMITS_UNTIL',
childId: this.childId,
time: this.timestamp
})
static parse = ({ childId, time }: SerializedSetUserDisableLimitsUntilAction) => (
new SetUserDisableLimitsUntilAction({
childId,
timestamp: time
})
)
}
export interface SerializedSetUserDisableLimitsUntilAction {
type: 'SET_USER_DISABLE_LIMITS_UNTIL'
childId: string
time: number
}
+52
View File
@@ -0,0 +1,52 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class SetUserTimezoneAction extends ParentAction {
readonly userId: string
readonly timezone: string
constructor ({ userId, timezone }: {
userId: string
timezone: string
}) {
super()
assertIdWithinFamily(userId)
this.userId = userId
this.timezone = timezone
}
serialize = (): SerializedSetUserTimezoneAction => ({
type: 'SET_USER_TIMEZONE',
userId: this.userId,
timezone: this.timezone
})
static parse = ({ userId, timezone }: SerializedSetUserTimezoneAction) => (
new SetUserTimezoneAction({ userId, timezone })
)
}
export interface SerializedSetUserTimezoneAction {
type: 'SET_USER_TIMEZONE'
userId: string
timezone: string
}
+36
View File
@@ -0,0 +1,36 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { AppLogicAction } from './basetypes'
export class SignOutAtDeviceAction extends AppLogicAction {
static instance = new SignOutAtDeviceAction()
private constructor () {
super()
}
serialize = (): SerializedSignOutAtDeviceAction => ({
type: 'SIGN_OUT_AT_DEVICE'
})
static parse = (action: SerializedSignOutAtDeviceAction) => SignOutAtDeviceAction.instance
}
export interface SerializedSignOutAtDeviceAction {
type: 'SIGN_OUT_AT_DEVICE'
}
+32
View File
@@ -0,0 +1,32 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { AppLogicAction } from './basetypes'
export class TriedDisablingDeviceAdminAction extends AppLogicAction {
constructor () {
super()
}
serialize = (): SerialiezdTriedDisablingDeviceAdminAction => ({
type: 'TRIED_DISABLING_DEVICE_ADMIN'
})
}
export interface SerialiezdTriedDisablingDeviceAdminAction {
type: 'TRIED_DISABLING_DEVICE_ADMIN'
}
+57
View File
@@ -0,0 +1,57 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { validateBitmask } from '../util/bitmask'
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class UpdateCategoryBlockedTimesAction extends ParentAction {
readonly categoryId: string
readonly blockedTimes: string
constructor ({ categoryId, blockedTimes }: {
categoryId: string
blockedTimes: string
}) {
super()
assertIdWithinFamily(categoryId)
validateBitmask(blockedTimes, 60 * 24 * 7 /* number of minutes per week */)
this.categoryId = categoryId
this.blockedTimes = blockedTimes
}
serialize = (): SerializedUpdateCategoryBlockedTimesAction => ({
type: 'UPDATE_CATEGORY_BLOCKED_TIMES',
categoryId: this.categoryId,
times: this.blockedTimes
})
static parse = ({ categoryId, times }: SerializedUpdateCategoryBlockedTimesAction) => (
new UpdateCategoryBlockedTimesAction({
categoryId,
blockedTimes: times
})
)
}
export interface SerializedUpdateCategoryBlockedTimesAction {
type: 'UPDATE_CATEGORY_BLOCKED_TIMES'
categoryId: string
times: string
}
@@ -0,0 +1,49 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class UpdateCategoryTemporarilyBlockedAction extends ParentAction {
readonly categoryId: string
readonly blocked: boolean
constructor ({ categoryId, blocked }: {categoryId: string, blocked: boolean}) {
super()
assertIdWithinFamily(categoryId)
this.categoryId = categoryId
this.blocked = blocked
}
serialize = (): SerializedUpdateCategoryTemporarilyBlockedAction => ({
type: 'UPDATE_CATEGORY_TEMPORARILY_BLOCKED',
categoryId: this.categoryId,
blocked: this.blocked
})
static parse = ({ categoryId, blocked }: SerializedUpdateCategoryTemporarilyBlockedAction) => (
new UpdateCategoryTemporarilyBlockedAction({ categoryId, blocked })
)
}
export interface SerializedUpdateCategoryTemporarilyBlockedAction {
type: 'UPDATE_CATEGORY_TEMPORARILY_BLOCKED'
categoryId: string
blocked: boolean
}
+49
View File
@@ -0,0 +1,49 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class UpdateCategoryTitleAction extends ParentAction {
readonly categoryId: string
readonly newTitle: string
constructor ({ categoryId, newTitle }: {categoryId: string, newTitle: string}) {
super()
assertIdWithinFamily(categoryId)
this.categoryId = categoryId
this.newTitle = newTitle
}
serialize = (): SerializedUpdateCategoryTitleAction => ({
type: 'UPDATE_CATEGORY_TITLE',
categoryId: this.categoryId,
newTitle: this.newTitle
})
static parse = ({ categoryId, newTitle }: SerializedUpdateCategoryTitleAction) => (
new UpdateCategoryTitleAction({ categoryId, newTitle })
)
}
export interface SerializedUpdateCategoryTitleAction {
type: 'UPDATE_CATEGORY_TITLE'
categoryId: string
newTitle: string
}
+56
View File
@@ -0,0 +1,56 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class UpdateDeviceNameAction extends ParentAction {
readonly deviceId: string
readonly name: string
constructor ({ deviceId, name }: {
deviceId: string
name: string
}) {
super()
this.deviceId = deviceId
this.name = name
assertIdWithinFamily(deviceId)
if (name.trim().length === 0) {
throw new Error('new device name must not be blank')
}
}
serialize = (): SerializedUpdateDeviceNameAction => ({
type: 'UPDATE_DEVICE_NAME',
deviceId: this.deviceId,
name: this.name
})
static parse = ({ deviceId, name }: SerializedUpdateDeviceNameAction) => (
new UpdateDeviceNameAction({ deviceId, name })
)
}
export interface SerializedUpdateDeviceNameAction {
type: 'UPDATE_DEVICE_NAME'
deviceId: string
name: string
}
+79
View File
@@ -0,0 +1,79 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { NewPermissionStatus } from '../model/newpermissionstatus'
import { ProtectionLevel } from '../model/protectionlevel'
import { RuntimePermissionStatus } from '../model/runtimepermissionstatus'
import { AppLogicAction } from './basetypes'
export class UpdateDeviceStatusAction extends AppLogicAction {
readonly newProtetionLevel?: ProtectionLevel
readonly newUsageStatsPermissionStatus?: RuntimePermissionStatus
readonly newNotificationAccessPermission?: NewPermissionStatus
readonly newAppVersion?: number
readonly didReboot: boolean
constructor ({ newProtetionLevel, newUsageStatsPermissionStatus, newNotificationAccessPermission, newAppVersion, didReboot }: {
newProtetionLevel?: ProtectionLevel
newUsageStatsPermissionStatus?: RuntimePermissionStatus
newNotificationAccessPermission?: NewPermissionStatus
newAppVersion?: number
didReboot: boolean
}) {
super()
if (newAppVersion !== undefined) {
if (!Number.isSafeInteger(newAppVersion) || (newAppVersion < 0)) {
throw new Error('invalid new ap version')
}
}
this.newProtetionLevel = newProtetionLevel
this.newUsageStatsPermissionStatus = newUsageStatsPermissionStatus
this.newNotificationAccessPermission = newNotificationAccessPermission
this.newAppVersion = newAppVersion
this.didReboot = didReboot
}
serialize = (): SerializedUpdateDeviceStatusAction => ({
type: 'UPDATE_DEVICE_STATUS',
protectionLevel: this.newProtetionLevel,
usageStats: this.newUsageStatsPermissionStatus,
notificationAccess: this.newNotificationAccessPermission,
appVersion: this.newAppVersion,
didReboot: this.didReboot
})
static parse = ({ protectionLevel, usageStats, notificationAccess, appVersion, didReboot }: SerializedUpdateDeviceStatusAction) => (
new UpdateDeviceStatusAction({
newProtetionLevel: protectionLevel,
newUsageStatsPermissionStatus: usageStats,
newNotificationAccessPermission: notificationAccess,
newAppVersion: appVersion,
didReboot: !!didReboot
})
)
}
export interface SerializedUpdateDeviceStatusAction {
type: 'UPDATE_DEVICE_STATUS'
protectionLevel?: ProtectionLevel
usageStats?: RuntimePermissionStatus
notificationAccess?: NewPermissionStatus
appVersion?: number
didReboot?: boolean
}
@@ -0,0 +1,55 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class UpdateNetworkTimeVerificationAction extends ParentAction {
readonly deviceId: string
readonly mode: 'disabled' | 'if possible' | 'enabled'
constructor ({ deviceId, mode }: {
deviceId: string
mode: 'disabled' | 'if possible' | 'enabled'
}) {
super()
assertIdWithinFamily(deviceId)
this.deviceId = deviceId
this.mode = mode
}
serialize = (): SerialiizedUpdateNetworkTimeVerificationAction => ({
type: 'UPDATE_NETWORK_TIME_VERIFICATION',
deviceId: this.deviceId,
mode: this.mode
})
static parse = ({ deviceId, mode }: SerialiizedUpdateNetworkTimeVerificationAction) => (
new UpdateNetworkTimeVerificationAction({
deviceId,
mode
})
)
}
export interface SerialiizedUpdateNetworkTimeVerificationAction {
type: 'UPDATE_NETWORK_TIME_VERIFICATION'
deviceId: string
mode: 'disabled' | 'if possible' | 'enabled'
}
@@ -0,0 +1,65 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class UpdateParentNotificationFlagsAction extends ParentAction {
readonly parentId: string
readonly flags: number
readonly set: boolean
constructor ({ parentId, flags, set }: {
parentId: string
flags: number
set: boolean
}) {
super()
assertIdWithinFamily(parentId)
if (!Number.isSafeInteger(flags)) {
throw new Error('flags must be an integer')
}
if (flags < 0 || flags > 1) {
throw new Error('flags are out of the valid range')
}
this.parentId = parentId
this.flags = flags
this.set = set
}
serialize = (): SerializedUpdateParentNotificationFlagsAction => ({
type: 'UPDATE_PARENT_NOTIFICATION_FLAGS',
parentId: this.parentId,
flags: this.flags,
set: this.set
})
static parse = ({ parentId, flags, set }: SerializedUpdateParentNotificationFlagsAction) => (
new UpdateParentNotificationFlagsAction({ parentId, flags, set })
)
}
export interface SerializedUpdateParentNotificationFlagsAction {
type: 'UPDATE_PARENT_NOTIFICATION_FLAGS'
parentId: string
flags: number
set: boolean
}
+79
View File
@@ -0,0 +1,79 @@
/*
* server component for the TimeLimit App
* Copyright (C) 2019 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, version 3 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import { assertIdWithinFamily } from '../util/token'
import { ParentAction } from './basetypes'
export class UpdateTimelimitRuleAction extends ParentAction {
readonly ruleId: string
readonly maximumTimeInMillis: number
readonly dayMask: number
readonly applyToExtraTimeUsage: boolean
constructor ({ ruleId, maximumTimeInMillis, dayMask, applyToExtraTimeUsage }: {
ruleId: string
maximumTimeInMillis: number
dayMask: number
applyToExtraTimeUsage: boolean
}) {
super()
this.ruleId = ruleId
this.maximumTimeInMillis = maximumTimeInMillis
this.dayMask = dayMask
this.applyToExtraTimeUsage = applyToExtraTimeUsage
assertIdWithinFamily(ruleId)
if (maximumTimeInMillis < 0 || (!Number.isSafeInteger(maximumTimeInMillis))) {
throw new Error('maximumTimeInMillis must be >= 0')
}
if (!(
Number.isSafeInteger(dayMask) ||
dayMask < 0 ||
dayMask > (1 | 2 | 4 | 8 | 16 | 32 | 64)
)) {
throw new Error('invalid day mask')
}
}
serialize = (): SerializedUpdateTimelimitRuleAction => ({
type: 'UPDATE_TIMELIMIT_RULE',
ruleId: this.ruleId,
time: this.maximumTimeInMillis,
days: this.dayMask,
extraTime: this.applyToExtraTimeUsage
})
static parse = ({ ruleId, time, days, extraTime }: SerializedUpdateTimelimitRuleAction) => (
new UpdateTimelimitRuleAction({
ruleId,
maximumTimeInMillis: time,
dayMask: days,
applyToExtraTimeUsage: extraTime
})
)
}
export interface SerializedUpdateTimelimitRuleAction {
type: 'UPDATE_TIMELIMIT_RULE'
ruleId: string
time: number
days: number
extraTime: boolean
}