diff --git a/docs/schema/SerializedParentAction.schema.json b/docs/schema/SerializedParentAction.schema.json
index 9d59d4f..edca800 100644
--- a/docs/schema/SerializedParentAction.schema.json
+++ b/docs/schema/SerializedParentAction.schema.json
@@ -410,6 +410,9 @@
},
"perDay": {
"type": "boolean"
+ },
+ "e": {
+ "type": "number"
}
},
"additionalProperties": false,
@@ -1458,6 +1461,9 @@
},
"perDay": {
"type": "boolean"
+ },
+ "e": {
+ "type": "number"
}
},
"additionalProperties": false,
diff --git a/docs/schema/serializedparentaction-definitions-serializedtimelimitrule-properties-e.md b/docs/schema/serializedparentaction-definitions-serializedtimelimitrule-properties-e.md
new file mode 100644
index 0000000..a76c551
--- /dev/null
+++ b/docs/schema/serializedparentaction-definitions-serializedtimelimitrule-properties-e.md
@@ -0,0 +1,15 @@
+# Untitled number in SerializedParentAction Schema
+
+```txt
+https://timelimit.io/SerializedParentAction#/definitions/SerializedTimeLimitRule/properties/e
+```
+
+
+
+| Abstract | Extensible | Status | Identifiable | Custom Properties | Additional Properties | Access Restrictions | Defined In |
+| :------------------ | :--------- | :------------- | :---------------------- | :---------------- | :-------------------- | :------------------ | :------------------------------------------------------------------------------------------------ |
+| Can be instantiated | No | Unknown status | Unknown identifiability | Forbidden | Allowed | none | [SerializedParentAction.schema.json\*](SerializedParentAction.schema.json "open original schema") |
+
+## e Type
+
+`number`
diff --git a/docs/schema/serializedparentaction-definitions-serializedtimelimitrule.md b/docs/schema/serializedparentaction-definitions-serializedtimelimitrule.md
index 6b7629d..b7790ba 100644
--- a/docs/schema/serializedparentaction-definitions-serializedtimelimitrule.md
+++ b/docs/schema/serializedparentaction-definitions-serializedtimelimitrule.md
@@ -28,6 +28,7 @@ https://timelimit.io/SerializedParentAction#/definitions/SerializedTimeLimitRule
| [dur](#dur) | `number` | Optional | cannot be null | [SerializedParentAction](serializedparentaction-definitions-serializedtimelimitrule-properties-dur.md "https://timelimit.io/SerializedParentAction#/definitions/SerializedTimeLimitRule/properties/dur") |
| [pause](#pause) | `number` | Optional | cannot be null | [SerializedParentAction](serializedparentaction-definitions-serializedtimelimitrule-properties-pause.md "https://timelimit.io/SerializedParentAction#/definitions/SerializedTimeLimitRule/properties/pause") |
| [perDay](#perday) | `boolean` | Optional | cannot be null | [SerializedParentAction](serializedparentaction-definitions-serializedtimelimitrule-properties-perday.md "https://timelimit.io/SerializedParentAction#/definitions/SerializedTimeLimitRule/properties/perDay") |
+| [e](#e) | `number` | Optional | cannot be null | [SerializedParentAction](serializedparentaction-definitions-serializedtimelimitrule-properties-e.md "https://timelimit.io/SerializedParentAction#/definitions/SerializedTimeLimitRule/properties/e") |
## ruleId
@@ -208,3 +209,21 @@ https://timelimit.io/SerializedParentAction#/definitions/SerializedTimeLimitRule
### perDay Type
`boolean`
+
+## e
+
+
+
+`e`
+
+* is optional
+
+* Type: `number`
+
+* cannot be null
+
+* defined in: [SerializedParentAction](serializedparentaction-definitions-serializedtimelimitrule-properties-e.md "https://timelimit.io/SerializedParentAction#/definitions/SerializedTimeLimitRule/properties/e")
+
+### e Type
+
+`number`
diff --git a/docs/schema/serializedparentaction-definitions-serializedupdatetimelimitruleaction-properties-e.md b/docs/schema/serializedparentaction-definitions-serializedupdatetimelimitruleaction-properties-e.md
new file mode 100644
index 0000000..9fcd00f
--- /dev/null
+++ b/docs/schema/serializedparentaction-definitions-serializedupdatetimelimitruleaction-properties-e.md
@@ -0,0 +1,15 @@
+# Untitled number in SerializedParentAction Schema
+
+```txt
+https://timelimit.io/SerializedParentAction#/definitions/SerializedUpdateTimelimitRuleAction/properties/e
+```
+
+
+
+| Abstract | Extensible | Status | Identifiable | Custom Properties | Additional Properties | Access Restrictions | Defined In |
+| :------------------ | :--------- | :------------- | :---------------------- | :---------------- | :-------------------- | :------------------ | :------------------------------------------------------------------------------------------------ |
+| Can be instantiated | No | Unknown status | Unknown identifiability | Forbidden | Allowed | none | [SerializedParentAction.schema.json\*](SerializedParentAction.schema.json "open original schema") |
+
+## e Type
+
+`number`
diff --git a/docs/schema/serializedparentaction-definitions-serializedupdatetimelimitruleaction-properties-expiresat.md b/docs/schema/serializedparentaction-definitions-serializedupdatetimelimitruleaction-properties-expiresat.md
new file mode 100644
index 0000000..679af8b
--- /dev/null
+++ b/docs/schema/serializedparentaction-definitions-serializedupdatetimelimitruleaction-properties-expiresat.md
@@ -0,0 +1,15 @@
+# Untitled number in SerializedParentAction Schema
+
+```txt
+https://timelimit.io/SerializedParentAction#/definitions/SerializedUpdateTimelimitRuleAction/properties/expiresAt
+```
+
+
+
+| Abstract | Extensible | Status | Identifiable | Custom Properties | Additional Properties | Access Restrictions | Defined In |
+| :------------------ | :--------- | :------------- | :---------------------- | :---------------- | :-------------------- | :------------------ | :------------------------------------------------------------------------------------------------ |
+| Can be instantiated | No | Unknown status | Unknown identifiability | Forbidden | Allowed | none | [SerializedParentAction.schema.json\*](SerializedParentAction.schema.json "open original schema") |
+
+## expiresAt Type
+
+`number`
diff --git a/docs/schema/serializedparentaction-definitions-serializedupdatetimelimitruleaction.md b/docs/schema/serializedparentaction-definitions-serializedupdatetimelimitruleaction.md
index 3efa439..a29ea46 100644
--- a/docs/schema/serializedparentaction-definitions-serializedupdatetimelimitruleaction.md
+++ b/docs/schema/serializedparentaction-definitions-serializedupdatetimelimitruleaction.md
@@ -28,6 +28,7 @@ https://timelimit.io/SerializedParentAction#/definitions/SerializedUpdateTimelim
| [dur](#dur) | `number` | Optional | cannot be null | [SerializedParentAction](serializedparentaction-definitions-serializedupdatetimelimitruleaction-properties-dur.md "https://timelimit.io/SerializedParentAction#/definitions/SerializedUpdateTimelimitRuleAction/properties/dur") |
| [pause](#pause) | `number` | Optional | cannot be null | [SerializedParentAction](serializedparentaction-definitions-serializedupdatetimelimitruleaction-properties-pause.md "https://timelimit.io/SerializedParentAction#/definitions/SerializedUpdateTimelimitRuleAction/properties/pause") |
| [perDay](#perday) | `boolean` | Optional | cannot be null | [SerializedParentAction](serializedparentaction-definitions-serializedupdatetimelimitruleaction-properties-perday.md "https://timelimit.io/SerializedParentAction#/definitions/SerializedUpdateTimelimitRuleAction/properties/perDay") |
+| [e](#e) | `number` | Optional | cannot be null | [SerializedParentAction](serializedparentaction-definitions-serializedupdatetimelimitruleaction-properties-e.md "https://timelimit.io/SerializedParentAction#/definitions/SerializedUpdateTimelimitRuleAction/properties/e") |
## type
@@ -216,3 +217,21 @@ https://timelimit.io/SerializedParentAction#/definitions/SerializedUpdateTimelim
### perDay Type
`boolean`
+
+## e
+
+
+
+`e`
+
+* is optional
+
+* Type: `number`
+
+* cannot be null
+
+* defined in: [SerializedParentAction](serializedparentaction-definitions-serializedupdatetimelimitruleaction-properties-e.md "https://timelimit.io/SerializedParentAction#/definitions/SerializedUpdateTimelimitRuleAction/properties/e")
+
+### e Type
+
+`number`
diff --git a/docs/schema/serializedparentaction.md b/docs/schema/serializedparentaction.md
index 728a25c..37c19f9 100644
--- a/docs/schema/serializedparentaction.md
+++ b/docs/schema/serializedparentaction.md
@@ -899,6 +899,7 @@ Reference this group by using
| [dur](#dur) | `number` | Optional | cannot be null | [SerializedParentAction](serializedparentaction-definitions-serializedtimelimitrule-properties-dur.md "https://timelimit.io/SerializedParentAction#/definitions/SerializedTimeLimitRule/properties/dur") |
| [pause](#pause) | `number` | Optional | cannot be null | [SerializedParentAction](serializedparentaction-definitions-serializedtimelimitrule-properties-pause.md "https://timelimit.io/SerializedParentAction#/definitions/SerializedTimeLimitRule/properties/pause") |
| [perDay](#perday) | `boolean` | Optional | cannot be null | [SerializedParentAction](serializedparentaction-definitions-serializedtimelimitrule-properties-perday.md "https://timelimit.io/SerializedParentAction#/definitions/SerializedTimeLimitRule/properties/perDay") |
+| [e](#e) | `number` | Optional | cannot be null | [SerializedParentAction](serializedparentaction-definitions-serializedtimelimitrule-properties-e.md "https://timelimit.io/SerializedParentAction#/definitions/SerializedTimeLimitRule/properties/e") |
### ruleId
@@ -1080,6 +1081,24 @@ Reference this group by using
`boolean`
+### e
+
+
+
+`e`
+
+* is optional
+
+* Type: `number`
+
+* cannot be null
+
+* defined in: [SerializedParentAction](serializedparentaction-definitions-serializedtimelimitrule-properties-e.md "https://timelimit.io/SerializedParentAction#/definitions/SerializedTimeLimitRule/properties/e")
+
+#### e Type
+
+`number`
+
## Definitions group SerializedDeleteCategoryAction
Reference this group by using
@@ -4397,6 +4416,7 @@ Reference this group by using
| [dur](#dur-1) | `number` | Optional | cannot be null | [SerializedParentAction](serializedparentaction-definitions-serializedupdatetimelimitruleaction-properties-dur.md "https://timelimit.io/SerializedParentAction#/definitions/SerializedUpdateTimelimitRuleAction/properties/dur") |
| [pause](#pause-1) | `number` | Optional | cannot be null | [SerializedParentAction](serializedparentaction-definitions-serializedupdatetimelimitruleaction-properties-pause.md "https://timelimit.io/SerializedParentAction#/definitions/SerializedUpdateTimelimitRuleAction/properties/pause") |
| [perDay](#perday-1) | `boolean` | Optional | cannot be null | [SerializedParentAction](serializedparentaction-definitions-serializedupdatetimelimitruleaction-properties-perday.md "https://timelimit.io/SerializedParentAction#/definitions/SerializedUpdateTimelimitRuleAction/properties/perDay") |
+| [e](#e-1) | `number` | Optional | cannot be null | [SerializedParentAction](serializedparentaction-definitions-serializedupdatetimelimitruleaction-properties-e.md "https://timelimit.io/SerializedParentAction#/definitions/SerializedUpdateTimelimitRuleAction/properties/e") |
### type
@@ -4586,6 +4606,24 @@ Reference this group by using
`boolean`
+### e
+
+
+
+`e`
+
+* is optional
+
+* Type: `number`
+
+* cannot be null
+
+* defined in: [SerializedParentAction](serializedparentaction-definitions-serializedupdatetimelimitruleaction-properties-e.md "https://timelimit.io/SerializedParentAction#/definitions/SerializedUpdateTimelimitRuleAction/properties/e")
+
+#### e Type
+
+`number`
+
## Definitions group SerializedUpdateUserFlagsAction
Reference this group by using
diff --git a/src/action/updatetimelimitrule.ts b/src/action/updatetimelimitrule.ts
index 6a582f6..b59dfd0 100644
--- a/src/action/updatetimelimitrule.ts
+++ b/src/action/updatetimelimitrule.ts
@@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
- * Copyright (C) 2019 - 2020 Jonas Lochmann
+ * Copyright (C) 2019 - 2024 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
@@ -32,11 +32,12 @@ export class UpdateTimelimitRuleAction extends ParentAction {
readonly sessionDurationMilliseconds: number
readonly sessionPauseMilliseconds: number
readonly perDay: boolean
+ readonly expiresAt?: number
constructor ({
ruleId, maximumTimeInMillis, dayMask, applyToExtraTimeUsage,
start, end, sessionDurationMilliseconds, sessionPauseMilliseconds,
- perDay
+ perDay, expiresAt
}: {
ruleId: string
maximumTimeInMillis: number
@@ -47,6 +48,7 @@ export class UpdateTimelimitRuleAction extends ParentAction {
sessionDurationMilliseconds: number
sessionPauseMilliseconds: number
perDay: boolean
+ expiresAt?: number
}) {
super()
@@ -59,6 +61,7 @@ export class UpdateTimelimitRuleAction extends ParentAction {
this.sessionDurationMilliseconds = sessionDurationMilliseconds
this.sessionPauseMilliseconds = sessionPauseMilliseconds
this.perDay = perDay
+ this.expiresAt = expiresAt
assertIdWithinFamily({ actionType, field: 'ruleId', value: ruleId })
@@ -92,9 +95,17 @@ export class UpdateTimelimitRuleAction extends ParentAction {
staticMessage: 'session duration lesser than zero'
})
}
+
+ if (expiresAt !== undefined) {
+ assertSafeInteger({ actionType, field: 'expiresAt', value: expiresAt })
+
+ if (expiresAt <= 0) {
+ throwOutOfRange({ actionType, field: 'expiresAt', value: expiresAt })
+ }
+ }
}
- static parse = ({ ruleId, time, days, extraTime, start, end, dur, pause, perDay }: SerializedUpdateTimelimitRuleAction) => (
+ static parse = ({ ruleId, time, days, extraTime, start, end, dur, pause, perDay, e }: SerializedUpdateTimelimitRuleAction) => (
new UpdateTimelimitRuleAction({
ruleId,
maximumTimeInMillis: time,
@@ -104,7 +115,8 @@ export class UpdateTimelimitRuleAction extends ParentAction {
end: end ?? MinuteOfDay.MAX,
sessionDurationMilliseconds: dur ?? 0,
sessionPauseMilliseconds: pause ?? 0,
- perDay: perDay ?? false
+ perDay: perDay ?? false,
+ expiresAt: e
})
)
}
@@ -120,4 +132,5 @@ export interface SerializedUpdateTimelimitRuleAction {
dur?: number
pause?: number
perDay?: boolean
+ e?: number
}
diff --git a/src/api/validator.ts b/src/api/validator.ts
index 408c934..4fab342 100644
--- a/src/api/validator.ts
+++ b/src/api/validator.ts
@@ -409,6 +409,9 @@ const definitions = {
},
"perDay": {
"type": "boolean"
+ },
+ "e": {
+ "type": "number"
}
},
"additionalProperties": false,
@@ -1417,6 +1420,9 @@ const definitions = {
},
"perDay": {
"type": "boolean"
+ },
+ "e": {
+ "type": "number"
}
},
"additionalProperties": false,
diff --git a/src/database/migration/migrations/20240408-add-rule-expires.ts b/src/database/migration/migrations/20240408-add-rule-expires.ts
new file mode 100644
index 0000000..7525f00
--- /dev/null
+++ b/src/database/migration/migrations/20240408-add-rule-expires.ts
@@ -0,0 +1,39 @@
+/*
+ * server component for the TimeLimit App
+ * Copyright (C) 2019 - 2024 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 .
+ */
+
+import { QueryInterface, Sequelize, Transaction } from 'sequelize'
+import { attributesVersion4 as ruleAttributes } from '../../timelimitrule'
+
+export async function up (queryInterface: QueryInterface, sequelize: Sequelize) {
+ await sequelize.transaction({
+ type: Transaction.TYPES.EXCLUSIVE
+ }, async (transaction) => {
+ await queryInterface.addColumn('TimelimitRules', 'expiresAt', {
+ ...ruleAttributes.expiresAt
+ }, {
+ transaction
+ })
+ })
+}
+
+export async function down (queryInterface: QueryInterface, sequelize: Sequelize) {
+ await sequelize.transaction({
+ type: Transaction.TYPES.EXCLUSIVE
+ }, async (transaction) => {
+ await queryInterface.removeColumn('TimelimitRules', 'expiresAt', { transaction })
+ })
+}
diff --git a/src/database/timelimitrule.ts b/src/database/timelimitrule.ts
index 1d0aa1f..367396f 100644
--- a/src/database/timelimitrule.ts
+++ b/src/database/timelimitrule.ts
@@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
- * Copyright (C) 2019 - 2021 Jonas Lochmann
+ * Copyright (C) 2019 - 2024 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -41,8 +41,13 @@ interface TimelimitRuleAttributesVersion3 {
perDay: number
}
+interface TimelimitRuleAttributesVersion4 {
+ expiresAt: string | null
+}
+
type TimelimitRuleAttributes = TimelimitRuleAttributesVersion1 &
- TimelimitRuleAttributesVersion2 & TimelimitRuleAttributesVersion3
+ TimelimitRuleAttributesVersion2 & TimelimitRuleAttributesVersion3 &
+ TimelimitRuleAttributesVersion4
export type TimelimitRuleModel = Sequelize.Model & TimelimitRuleAttributes
export type TimelimitRuleModelStatic = typeof Sequelize.Model & {
@@ -137,10 +142,22 @@ export const attributesVersion3: SequelizeAttributes = {
+ expiresAt: {
+ type: Sequelize.BIGINT,
+ validate: {
+ min: 1
+ },
+ allowNull: true,
+ defaultValue: null
+ }
+}
+
export const attributes: SequelizeAttributes = {
...attributesVersion1,
...attributesVersion2,
- ...attributesVersion3
+ ...attributesVersion3,
+ ...attributesVersion4
}
export const createTimelimitRuleModel = (sequelize: Sequelize.Sequelize): TimelimitRuleModelStatic => sequelize.define('TimelimitRule', attributes) as TimelimitRuleModelStatic
diff --git a/src/function/sync/apply-actions/dispatch-parent-action/createtimelimitrule.ts b/src/function/sync/apply-actions/dispatch-parent-action/createtimelimitrule.ts
index 8e98ceb..6796b42 100644
--- a/src/function/sync/apply-actions/dispatch-parent-action/createtimelimitrule.ts
+++ b/src/function/sync/apply-actions/dispatch-parent-action/createtimelimitrule.ts
@@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
- * Copyright (C) 2019 - 2022 Jonas Lochmann
+ * Copyright (C) 2019 - 2024 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -55,7 +55,8 @@ export async function dispatchCreateTimeLimitRule ({ action, cache, fromChildSel
endMinuteOfDay: action.rule.end,
sessionDurationMilliseconds: action.rule.sessionDurationMilliseconds,
sessionPauseMilliseconds: action.rule.sessionPauseMilliseconds,
- perDay: action.rule.perDay ? 1 : 0
+ perDay: action.rule.perDay ? 1 : 0,
+ expiresAt: action.rule.expiresAt ? action.rule.expiresAt.toString() : null
}, { transaction: cache.transaction })
cache.categoriesWithModifiedTimeLimitRules.add(action.rule.categoryId)
diff --git a/src/function/sync/apply-actions/dispatch-parent-action/updatetimelimitrule.ts b/src/function/sync/apply-actions/dispatch-parent-action/updatetimelimitrule.ts
index a39a026..afae222 100644
--- a/src/function/sync/apply-actions/dispatch-parent-action/updatetimelimitrule.ts
+++ b/src/function/sync/apply-actions/dispatch-parent-action/updatetimelimitrule.ts
@@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
- * Copyright (C) 2019 - 2022 Jonas Lochmann
+ * Copyright (C) 2019 - 2024 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
@@ -81,7 +81,8 @@ export async function dispatchUpdateTimelimitRule ({
action.sessionDurationMilliseconds <= ruleEntry.sessionDurationMilliseconds &&
action.sessionPauseMilliseconds >= ruleEntry.sessionPauseMilliseconds
)) &&
- (!action.perDay || ruleEntry.perDay || countOldAffectedDays <= 1)
+ (!action.perDay || ruleEntry.perDay || countOldAffectedDays <= 1) &&
+ (action.expiresAt === undefined || (ruleEntry.expiresAt !== null && action.expiresAt >= parseInt(ruleEntry.expiresAt, 10)))
if (!isAtLeastAsStrictAsPreviously) {
throw new CanNotRelaxRestrictionsSelfLimitException()
@@ -96,6 +97,7 @@ export async function dispatchUpdateTimelimitRule ({
ruleEntry.sessionDurationMilliseconds = action.sessionDurationMilliseconds
ruleEntry.sessionPauseMilliseconds = action.sessionPauseMilliseconds
ruleEntry.perDay = action.perDay ? 1 : 0
+ ruleEntry.expiresAt = action.expiresAt ? action.expiresAt.toString() : null
await ruleEntry.save({ transaction: cache.transaction })
diff --git a/src/function/sync/get-server-data-status/category/rules.ts b/src/function/sync/get-server-data-status/category/rules.ts
index 263e01a..4405081 100644
--- a/src/function/sync/get-server-data-status/category/rules.ts
+++ b/src/function/sync/get-server-data-status/category/rules.ts
@@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
- * Copyright (C) 2019 - 2020 Jonas Lochmann
+ * Copyright (C) 2019 - 2024 Jonas Lochmann
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -45,7 +45,8 @@ export async function getRules ({ database, transaction, categoryIdsToSyncRules,
'endMinuteOfDay',
'sessionDurationMilliseconds',
'sessionPauseMilliseconds',
- 'perDay'
+ 'perDay',
+ 'expiresAt'
],
transaction
})).map((item) => ({
@@ -58,7 +59,8 @@ export async function getRules ({ database, transaction, categoryIdsToSyncRules,
endMinuteOfDay: item.endMinuteOfDay,
sessionDurationMilliseconds: item.sessionDurationMilliseconds,
sessionPauseMilliseconds: item.sessionPauseMilliseconds,
- perDay: item.perDay
+ perDay: item.perDay,
+ expiresAt: item.expiresAt ? parseInt(item.expiresAt, 10) : undefined
}))
const getCategoryRulesVersion = (categoryId: string) => (
@@ -76,7 +78,8 @@ export async function getRules ({ database, transaction, categoryIdsToSyncRules,
end: item.endMinuteOfDay,
session: item.sessionDurationMilliseconds,
pause: item.sessionPauseMilliseconds,
- perDay: item.perDay !== 0 ? true : false
+ perDay: item.perDay !== 0 ? true : false,
+ e: item.expiresAt
})),
version: getCategoryRulesVersion(categoryId)
}))
diff --git a/src/function/sync/get-server-data-status/index.ts b/src/function/sync/get-server-data-status/index.ts
index ec708ae..f5d57d7 100644
--- a/src/function/sync/get-server-data-status/index.ts
+++ b/src/function/sync/get-server-data-status/index.ts
@@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
- * Copyright (C) 2019 - 2022 Jonas Lochmann
+ * Copyright (C) 2019 - 2024 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
@@ -58,7 +58,7 @@ export const generateServerDataStatus = async ({
familyEntry.hasFullVersion ? parseInt(familyEntry.fullVersionUntil, 10) : 0
),
message: await getStatusMessage({ database, transaction }) || undefined,
- apiLevel: 7
+ apiLevel: 8
}
if (familyEntry.deviceListVersion !== clientStatus.devices) {
diff --git a/src/model/timelimitrule.ts b/src/model/timelimitrule.ts
index f346dc5..9c0716d 100644
--- a/src/model/timelimitrule.ts
+++ b/src/model/timelimitrule.ts
@@ -1,6 +1,6 @@
/*
* server component for the TimeLimit App
- * Copyright (C) 2019 - 2020 Jonas Lochmann
+ * Copyright (C) 2019 - 2024 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
@@ -29,11 +29,12 @@ export class TimelimitRule {
readonly sessionDurationMilliseconds: number
readonly sessionPauseMilliseconds: number
readonly perDay: boolean
+ readonly expiresAt?: number
constructor ({
ruleId, categoryId, maxTimeInMillis, dayMask, applyToExtraTimeUsage,
start, end, sessionDurationMilliseconds, sessionPauseMilliseconds,
- perDay
+ perDay, expiresAt
}: {
ruleId: string
categoryId: string
@@ -45,6 +46,7 @@ export class TimelimitRule {
sessionDurationMilliseconds: number
sessionPauseMilliseconds: number
perDay: boolean
+ expiresAt?: number
}) {
this.ruleId = ruleId
this.categoryId = categoryId
@@ -56,6 +58,7 @@ export class TimelimitRule {
this.sessionDurationMilliseconds = sessionDurationMilliseconds
this.sessionPauseMilliseconds = sessionPauseMilliseconds
this.perDay = perDay
+ this.expiresAt = expiresAt
assertIdWithinFamily(ruleId)
assertIdWithinFamily(categoryId)
@@ -88,6 +91,14 @@ export class TimelimitRule {
if (sessionDurationMilliseconds < 0 || sessionPauseMilliseconds < 0) {
throw new ParseTimeLimitRuleException()
}
+
+ if (expiresAt !== undefined) {
+ if (!Number.isSafeInteger(expiresAt)) throw new ParseTimeLimitRuleException()
+
+ if (expiresAt <= 0) {
+ throw new ParseTimeLimitRuleException()
+ }
+ }
}
serialize = (): SerializedTimeLimitRule => ({
@@ -99,10 +110,11 @@ export class TimelimitRule {
start: this.start,
end: this.end,
pause: this.sessionPauseMilliseconds,
- dur: this.sessionDurationMilliseconds
+ dur: this.sessionDurationMilliseconds,
+ e: this.expiresAt
})
- static parse = ({ ruleId, categoryId, time, days, extraTime, start, end, dur, pause, perDay }: SerializedTimeLimitRule) => (
+ static parse = ({ ruleId, categoryId, time, days, extraTime, start, end, dur, pause, perDay, e }: SerializedTimeLimitRule) => (
new TimelimitRule({
ruleId,
categoryId,
@@ -113,7 +125,8 @@ export class TimelimitRule {
end: end ?? MinuteOfDay.MAX,
sessionDurationMilliseconds: dur ?? 0,
sessionPauseMilliseconds: pause ?? 0,
- perDay: perDay ?? false
+ perDay: perDay ?? false,
+ expiresAt: e
})
)
}
@@ -129,6 +142,7 @@ export interface SerializedTimeLimitRule {
dur?: number
pause?: number
perDay?: boolean
+ e?: number // expiresAt
}
export class ParseTimeLimitRuleException extends Error {}