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
+42
View File
@@ -0,0 +1,42 @@
/*
* 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 * as Sequelize from 'sequelize'
import { familyIdColumn, idWithinFamilyColumn, labelColumn, timestampColumn } from './columns'
import { SequelizeAttributes } from './types'
export interface AddDeviceTokenAttributes {
token: string
familyId: string
deviceId: string
createdAt: string
}
export type AddDeviceTokenInstance = Sequelize.Instance<AddDeviceTokenAttributes> & AddDeviceTokenAttributes
export type AddDeviceTokenModel = Sequelize.Model<AddDeviceTokenInstance, AddDeviceTokenAttributes>
export const attributes: SequelizeAttributes<AddDeviceTokenAttributes> = {
token: {
...labelColumn,
primaryKey: true
},
familyId: { ...familyIdColumn },
deviceId: { ...idWithinFamilyColumn },
createdAt: { ...timestampColumn }
}
export const createAddDeviceTokenModel = (sequelize: Sequelize.Sequelize): AddDeviceTokenModel => sequelize.define<AddDeviceTokenInstance, AddDeviceTokenInstance>('AddDeviceToken', attributes)
+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 * as Sequelize from 'sequelize'
import { AppRecommendation, appRecommendationValues } from '../model/apprecommendation'
import { booleanColumn, createEnumColumn, familyIdColumn, idWithinFamilyColumn, optionalLabelColumn } from './columns'
import { SequelizeAttributes } from './types'
export interface AppAttributes {
familyId: string
deviceId: string
packageName: string
title: string
isLaunchable: boolean
recommendation: AppRecommendation
}
export type AppInstance = Sequelize.Instance<AppAttributes> & AppAttributes
export type AppModel = Sequelize.Model<AppInstance, AppAttributes>
export const attributes: SequelizeAttributes<AppAttributes> = {
familyId: {
...familyIdColumn,
primaryKey: true
},
deviceId: {
...idWithinFamilyColumn,
primaryKey: true
},
packageName: {
type: Sequelize.STRING,
allowNull: false,
validate: {
notEmpty: true
},
primaryKey: true
},
title: { ...optionalLabelColumn },
isLaunchable: { ...booleanColumn },
recommendation: createEnumColumn(appRecommendationValues)
}
export const createAppModel = (sequelize: Sequelize.Sequelize): AppModel => sequelize.define<AppInstance, AppAttributes>('App', attributes)
+46
View File
@@ -0,0 +1,46 @@
/*
* 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 * as Sequelize from 'sequelize'
import { authTokenColumn, timestampColumn } from './columns'
import { SequelizeAttributes } from './types'
export interface AuthTokenAttributes {
token: string
mail: string
createdAt: string
}
export type AuthTokenInstance = Sequelize.Instance<AuthTokenAttributes> & AuthTokenAttributes
export type AuthTokenModel = Sequelize.Model<AuthTokenInstance, AuthTokenAttributes>
export const attributes: SequelizeAttributes<AuthTokenAttributes> = {
token: {
...authTokenColumn,
primaryKey: true
},
mail: {
type: Sequelize.STRING,
allowNull: false,
validate: {
notEmpty: true
}
},
createdAt: { ...timestampColumn }
}
export const createAuthtokenModel = (sequelize: Sequelize.Sequelize): AuthTokenModel => sequelize.define<AuthTokenInstance, AuthTokenAttributes>('AuthToken', attributes)
+90
View File
@@ -0,0 +1,90 @@
/*
* 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 * as Sequelize from 'sequelize'
import { serializedBitmaskRegex } from '../util/bitmask'
import { booleanColumn, familyIdColumn, idWithinFamilyColumn, labelColumn, optionalIdWithinFamilyColumn, versionColumn } from './columns'
import { SequelizeAttributes } from './types'
export interface CategoryAttributesVersion1 {
familyId: string
categoryId: string
childId: string
title: string
blockedMinutesInWeek: string
extraTimeInMillis: number
temporarilyBlocked: boolean
baseVersion: string
assignedAppsVersion: string
timeLimitRulesVersion: string
usedTimesVersion: string
}
export interface CategoryAttributesVersion2 {
parentCategoryId: string
}
export type CategoryAttributes = CategoryAttributesVersion1 & CategoryAttributesVersion2
export type CategoryInstance = Sequelize.Instance<CategoryAttributes> & CategoryAttributes
export type CategoryModel = Sequelize.Model<CategoryInstance, CategoryAttributes>
export const attributesVersion1: SequelizeAttributes<CategoryAttributesVersion1> = {
familyId: {
...familyIdColumn,
primaryKey: true
},
categoryId: {
...idWithinFamilyColumn,
primaryKey: true
},
childId: { ...idWithinFamilyColumn },
title: { ...labelColumn },
blockedMinutesInWeek: {
type: Sequelize.TEXT,
allowNull: false,
validate: {
is: serializedBitmaskRegex
}
},
extraTimeInMillis: {
type: Sequelize.INTEGER,
allowNull: false,
validate: {
min: 0
}
},
temporarilyBlocked: { ...booleanColumn },
baseVersion: { ...versionColumn },
assignedAppsVersion: { ...versionColumn },
timeLimitRulesVersion: { ...versionColumn },
usedTimesVersion: { ...versionColumn }
}
export const attributesVersion2: SequelizeAttributes<CategoryAttributesVersion2> = {
parentCategoryId: {
...optionalIdWithinFamilyColumn,
defaultValue: ''
}
}
export const attributes: SequelizeAttributes<CategoryAttributes> = {
...attributesVersion1,
...attributesVersion2
}
export const createCategoryModel = (sequelize: Sequelize.Sequelize): CategoryModel => sequelize.define<CategoryInstance, CategoryAttributes>('Category', attributes)
+50
View File
@@ -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 * as Sequelize from 'sequelize'
import { familyIdColumn, idWithinFamilyColumn } from './columns'
import { SequelizeAttributes } from './types'
export interface CategoryAppAttributes {
familyId: string
categoryId: string
packageName: string
}
export type CategoryAppInstance = Sequelize.Instance<CategoryAppAttributes> & CategoryAppAttributes
export type CategoryAppModel = Sequelize.Model<CategoryAppInstance, CategoryAppAttributes>
export const attributes: SequelizeAttributes<CategoryAppAttributes> = {
familyId: {
...familyIdColumn,
primaryKey: true
},
categoryId: {
...idWithinFamilyColumn,
primaryKey: true
},
packageName: {
type: Sequelize.STRING,
allowNull: false,
validate: {
notEmpty: true
},
primaryKey: true
}
}
export const createCategoryAppModel = (sequelize: Sequelize.Sequelize): CategoryAppModel => sequelize.define<CategoryAppInstance, CategoryAppAttributes>('CategoryApp', attributes)
+97
View File
@@ -0,0 +1,97 @@
/*
* 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 * as Sequelize from 'sequelize'
export const familyIdColumn: Sequelize.DefineAttributeColumnOptions = {
type: Sequelize.STRING(10),
allowNull: false,
validate: {
notEmpty: true,
is: /^[a-zA-Z0-9]{10}$/
}
}
export const idWithinFamilyColumn: Sequelize.DefineAttributeColumnOptions = {
type: Sequelize.STRING(6),
allowNull: false,
validate: {
notEmpty: true,
is: /^[a-zA-Z0-9]{6}$/
}
}
export const optionalIdWithinFamilyColumn: Sequelize.DefineAttributeColumnOptions = {
type: Sequelize.STRING(6),
allowNull: false,
validate: {
is: /^([a-zA-Z0-9]{6})?$/
}
}
export const versionColumn: Sequelize.DefineAttributeColumnOptions = {
type: Sequelize.STRING(4),
allowNull: false,
validate: {
notEmpty: true,
is: /^[a-zA-Z0-9]{4}$/
}
}
export const labelColumn: Sequelize.DefineAttributeColumnOptions = {
type: Sequelize.STRING,
allowNull: false,
validate: {
notEmpty: true
}
}
export const optionalLabelColumn: Sequelize.DefineAttributeColumnOptions = {
type: Sequelize.STRING,
allowNull: false
}
export const createEnumColumn = (possibleValues: Array<string>): Sequelize.DefineAttributeColumnOptions => ({
type: Sequelize.STRING,
allowNull: false,
validate: {
isIn: [possibleValues],
notEmpty: true
}
})
// warning: this results in an string field
export const timestampColumn: Sequelize.DefineAttributeColumnOptions = {
type: Sequelize.BIGINT,
allowNull: false,
validate: {
min: 0
}
}
export const booleanColumn: Sequelize.DefineAttributeColumnOptions = {
type: Sequelize.BOOLEAN,
allowNull: false
}
export const authTokenColumn: Sequelize.DefineAttributeColumnOptions = {
type: Sequelize.STRING(32),
allowNull: false,
validate: {
notEmpty: true,
is: /^[a-zA-Z0-9]{32}$/
}
}
+204
View File
@@ -0,0 +1,204 @@
/*
* 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 * as Sequelize from 'sequelize'
import { NewPermissionStatus, newPermissionStatusValues } from '../model/newpermissionstatus'
import { ProtectionLevel, protetionLevels } from '../model/protectionlevel'
import { RuntimePermissionStatus, runtimePermissionStatusValues } from '../model/runtimepermissionstatus'
import { authTokenColumn, booleanColumn, createEnumColumn, familyIdColumn, idWithinFamilyColumn, labelColumn, optionalIdWithinFamilyColumn, timestampColumn, versionColumn } from './columns'
import { SequelizeAttributes } from './types'
export interface DeviceAttributesVersion1 {
familyId: string
deviceId: string
name: string
model: string
addedAt: string
currentUserId: string
installedAppsVersion: string
deviceAuthToken: string
networkTime: 'disabled' | 'if possible' | 'enabled'
nextSequenceNumber: number
currentProtectionLevel: ProtectionLevel
highestProtectionLevel: ProtectionLevel
currentUsageStatsPermission: RuntimePermissionStatus
highestUsageStatsPermission: RuntimePermissionStatus
currentNotificationAccessPermission: NewPermissionStatus
highestNotificationAccessPermission: NewPermissionStatus
currentAppVersion: number
highestAppVersion: number
triedDisablingDeviceAdmin: boolean
hadManipulation: boolean
}
export interface DeviceAttributesVersion2 {
lastConnectivity: string
notSeenForLongTime: boolean
didDeviceReportUninstall: boolean
}
export interface DeviceAttributesVersion3 {
isUserKeptSignedIn: boolean
}
export interface DeviceAttributesVersion4 {
showDeviceConnected: boolean
}
export interface DeviceAttributesVersion5 {
defaultUserId: string
defaultUserTimeout: number
}
export interface DeviceAttributesVersion6 {
didReboot: boolean
considerRebootManipulation: boolean
}
export type DeviceAttributes = DeviceAttributesVersion1 & DeviceAttributesVersion2 &
DeviceAttributesVersion3 & DeviceAttributesVersion4 & DeviceAttributesVersion5 &
DeviceAttributesVersion6
export type DeviceInstance = Sequelize.Instance<DeviceAttributes> & DeviceAttributes
export type DeviceModel = Sequelize.Model<DeviceInstance, DeviceAttributes>
export const attributesVersion1: SequelizeAttributes<DeviceAttributesVersion1> = {
familyId: {
...familyIdColumn,
primaryKey: true
},
deviceId: {
...idWithinFamilyColumn,
primaryKey: true
},
name: { ...labelColumn },
model: { ...labelColumn },
addedAt: { ...timestampColumn },
currentUserId: { ...optionalIdWithinFamilyColumn },
installedAppsVersion: { ...versionColumn },
deviceAuthToken: { ...authTokenColumn },
networkTime: createEnumColumn(['disabled', 'if possible', 'enabled']),
nextSequenceNumber: {
type: Sequelize.INTEGER,
allowNull: false
},
currentProtectionLevel: createEnumColumn(protetionLevels),
highestProtectionLevel: createEnumColumn(protetionLevels),
currentUsageStatsPermission: createEnumColumn(runtimePermissionStatusValues),
highestUsageStatsPermission: createEnumColumn(runtimePermissionStatusValues),
currentNotificationAccessPermission: createEnumColumn(newPermissionStatusValues),
highestNotificationAccessPermission: createEnumColumn(newPermissionStatusValues),
currentAppVersion: {
type: Sequelize.INTEGER,
allowNull: false,
validate: {
min: 0
}
},
highestAppVersion: {
type: Sequelize.INTEGER,
allowNull: false,
validate: {
min: 0
}
},
triedDisablingDeviceAdmin: { ...booleanColumn },
hadManipulation: { ...booleanColumn }
}
export const attributesVersion2: SequelizeAttributes<DeviceAttributesVersion2> = {
lastConnectivity: {
...timestampColumn,
defaultValue: 0
},
notSeenForLongTime: {
...booleanColumn,
defaultValue: false
},
didDeviceReportUninstall: {
...booleanColumn,
defaultValue: false
}
}
export const attributesVersion3: SequelizeAttributes<DeviceAttributesVersion3> = {
isUserKeptSignedIn: {
...booleanColumn,
defaultValue: false
}
}
export const attributesVersion4: SequelizeAttributes<DeviceAttributesVersion4> = {
showDeviceConnected: {
...booleanColumn,
defaultValue: false
}
}
export const attributesVersion5: SequelizeAttributes<DeviceAttributesVersion5> = {
defaultUserId: {
...optionalIdWithinFamilyColumn,
defaultValue: ''
},
defaultUserTimeout: {
type: Sequelize.INTEGER,
allowNull: false,
defaultValue: 0,
validate: {
min: 0
}
}
}
export const attributesVersion6: SequelizeAttributes<DeviceAttributesVersion6> = {
didReboot: {
...booleanColumn,
defaultValue: false
},
considerRebootManipulation: {
...booleanColumn,
defaultValue: false
}
}
export const attributes: SequelizeAttributes<DeviceAttributes> = {
...attributesVersion1,
...attributesVersion2,
...attributesVersion3,
...attributesVersion4,
...attributesVersion5,
...attributesVersion6
}
export const createDeviceModel = (sequelize: Sequelize.Sequelize): DeviceModel => sequelize.define<DeviceInstance, DeviceAttributes>('Device', attributes)
export const hasDeviceManipulation = (device: DeviceAttributes) => {
const manipulationOfProtectionLevel = device.currentProtectionLevel !== device.highestProtectionLevel
const manipulationOfUsageStats = device.currentUsageStatsPermission !== device.highestUsageStatsPermission
const manipulationOfNotificationAccess = device.currentNotificationAccessPermission !== device.highestNotificationAccessPermission
const manipulationOfAppVersion = device.currentAppVersion !== device.highestAppVersion
const hasActiveManipulationWarning = manipulationOfProtectionLevel ||
manipulationOfUsageStats ||
manipulationOfNotificationAccess ||
manipulationOfAppVersion ||
device.triedDisablingDeviceAdmin ||
device.didReboot
const hasAnyManipulation = hasActiveManipulationWarning || device.hadManipulation
return hasAnyManipulation
}
+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 * as Sequelize from 'sequelize'
import { booleanColumn, familyIdColumn, optionalLabelColumn, timestampColumn, versionColumn } from './columns'
import { SequelizeAttributes } from './types'
export interface FamilyAttributes {
familyId: string
name: string
createdAt: string
userListVersion: string
deviceListVersion: string
fullVersionUntil: string
hasFullVersion: boolean
}
export type FamilyInstance = Sequelize.Instance<FamilyAttributes> & FamilyAttributes
export type FamilyModel = Sequelize.Model<FamilyInstance, FamilyAttributes>
export const attributes: SequelizeAttributes<FamilyAttributes> = {
familyId: {
...familyIdColumn,
primaryKey: true
},
name: { ...optionalLabelColumn },
createdAt: { ...timestampColumn },
userListVersion: { ...versionColumn },
deviceListVersion: { ...versionColumn },
fullVersionUntil: { ...timestampColumn },
hasFullVersion: { ...booleanColumn }
}
export const createFamilyModel = (sequelize: Sequelize.Sequelize): FamilyModel => sequelize.define<FamilyInstance, FamilyAttributes>('Family', attributes)
+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 * as Sequelize from 'sequelize'
import { AddDeviceTokenModel, createAddDeviceTokenModel } from './adddevicetoken'
import { AppModel, createAppModel } from './app'
import { AuthTokenModel, createAuthtokenModel } from './authtoken'
import { CategoryModel, createCategoryModel } from './category'
import { CategoryAppModel, createCategoryAppModel } from './categoryapp'
import { createDeviceModel, DeviceModel } from './device'
import { createFamilyModel, FamilyModel } from './family'
import { createMailLoginTokenModel, MailLoginTokenModel } from './maillogintoken'
import { createUmzug } from './migration/umzug'
import { createOldDeviceModel, OldDeviceModel } from './olddevice'
import { createPurchaseModel, PurchaseModel } from './purchase'
import { createTimelimitRuleModel, TimelimitRuleModel } from './timelimitrule'
import { createUsedTimeModel, UsedTimeModel } from './usedtime'
import { createUserModel, UserModel } from './user'
export interface Database {
addDeviceToken: AddDeviceTokenModel
authtoken: AuthTokenModel
app: AppModel
category: CategoryModel
categoryApp: CategoryAppModel
device: DeviceModel
family: FamilyModel
mailLoginToken: MailLoginTokenModel
oldDevice: OldDeviceModel
purchase: PurchaseModel
timelimitRule: TimelimitRuleModel
usedTime: UsedTimeModel
user: UserModel
transaction: <T> (autoCallback: (t: Sequelize.Transaction) => Promise<T>) => Promise<T>
}
const createDatabase = (sequelize: Sequelize.Sequelize): Database => ({
addDeviceToken: createAddDeviceTokenModel(sequelize),
authtoken: createAuthtokenModel(sequelize),
app: createAppModel(sequelize),
category: createCategoryModel(sequelize),
categoryApp: createCategoryAppModel(sequelize),
device: createDeviceModel(sequelize),
family: createFamilyModel(sequelize),
mailLoginToken: createMailLoginTokenModel(sequelize),
oldDevice: createOldDeviceModel(sequelize),
purchase: createPurchaseModel(sequelize),
timelimitRule: createTimelimitRuleModel(sequelize),
usedTime: createUsedTimeModel(sequelize),
user: createUserModel(sequelize),
transaction: <T> (autoCallback: (transaction: Sequelize.Transaction) => Promise<T>) => (sequelize.transaction({
isolationLevel: Sequelize.Transaction.ISOLATION_LEVELS.READ_COMMITTED
}, autoCallback) as any) as Promise<T>
})
export const sequelize = new Sequelize(process.env.DATABASE_URL || 'sqlite://test.db', {
define: {
timestamps: false
},
operatorsAliases: false,
logging: false
})
export const defaultDatabase = createDatabase(sequelize)
export const defaultUmzug = createUmzug(sequelize)
+62
View File
@@ -0,0 +1,62 @@
/*
* 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 * as Sequelize from 'sequelize'
import { authTokenColumn, timestampColumn } from './columns'
import { SequelizeAttributes } from './types'
export interface MailLoginTokenAttributes {
mailLoginToken: string
receivedCode: string
mail: string
createdAt: string
remainingAttempts: number
}
export type MailLoginTokenInstance = Sequelize.Instance<MailLoginTokenAttributes> & MailLoginTokenAttributes
export type MailLoginTokenModel = Sequelize.Model<MailLoginTokenInstance, MailLoginTokenAttributes>
export const attributes: SequelizeAttributes<MailLoginTokenAttributes> = {
mailLoginToken: {
...authTokenColumn,
primaryKey: true
},
receivedCode: {
type: Sequelize.STRING,
allowNull: false,
validate: {
notEmpty: true
}
},
mail: {
type: Sequelize.STRING,
allowNull: false,
validate: {
notEmpty: true
}
},
createdAt: { ...timestampColumn },
remainingAttempts: {
type: Sequelize.INTEGER,
allowNull: false,
validate: {
min: 0
}
}
}
export const createMailLoginTokenModel = (sequelize: Sequelize.Sequelize): MailLoginTokenModel => sequelize.define<MailLoginTokenInstance, MailLoginTokenAttributes>('MailLoginToken', attributes)
@@ -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 { QueryInterface, Sequelize } from 'sequelize'
import { attributes as addDeviceTokenAttributes } from '../../adddevicetoken'
import { attributes as appAttributes } from '../../app'
import { attributes as authTokenAttributes } from '../../authtoken'
import { attributesVersion1 as categoryAttributes } from '../../category'
import { attributes as categoryAppAttributes } from '../../categoryapp'
import { attributesVersion1 as deviceAttributes } from '../../device'
import { attributes as familyAttributes } from '../../family'
import { attributes as purchaseAttributes } from '../../purchase'
import { attributes as timelimitruleAttributes } from '../../timelimitrule'
import { attributesVersion1 as usedTimeAttribute } from '../../usedtime'
import { attributesVersion1 as userAttributes } from '../../user'
export async function up (queryInterface: QueryInterface, sequelize: Sequelize) {
await sequelize.transaction({
type: 'EXCLUSIVE'
}, async (transaction) => {
await queryInterface.createTable('AddDeviceTokens', addDeviceTokenAttributes, { transaction })
await queryInterface.createTable('Apps', appAttributes, { transaction })
await queryInterface.createTable('AuthTokens', authTokenAttributes, { transaction })
await queryInterface.createTable('Categories', categoryAttributes, { transaction })
await queryInterface.createTable('CategoryApps', categoryAppAttributes, { transaction })
await queryInterface.createTable('Devices', deviceAttributes, { transaction })
await queryInterface.createTable('Families', familyAttributes, { transaction })
await queryInterface.createTable('Purchases', purchaseAttributes, { transaction })
await queryInterface.createTable('TimelimitRules', timelimitruleAttributes, { transaction })
await queryInterface.createTable('UsedTimes', usedTimeAttribute, { transaction })
await queryInterface.createTable('Users', userAttributes, { transaction })
})
}
export async function down () {
throw new Error('not possible')
}
@@ -0,0 +1,58 @@
/*
* 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 { QueryInterface, Sequelize } from 'sequelize'
import { attributesVersion2 } from '../../device'
import { attributes as oldDeviceAttributes } from '../../olddevice'
export async function up (queryInterface: QueryInterface, sequelize: Sequelize) {
await sequelize.transaction({
type: 'EXCLUSIVE'
}, async (transaction) => {
await queryInterface.addColumn('Devices', 'lastConnectivity', {
...attributesVersion2.lastConnectivity
}, {
transaction
})
await queryInterface.addColumn('Devices', 'notSeenForLongTime', {
...attributesVersion2.notSeenForLongTime
}, {
transaction
})
await queryInterface.addColumn('Devices', 'didDeviceReportUninstall', {
...attributesVersion2.didDeviceReportUninstall
}, {
transaction
})
await queryInterface.createTable('OldDevices', oldDeviceAttributes, { transaction })
})
}
export async function down (queryInterface: QueryInterface, sequelize: Sequelize) {
await sequelize.transaction({
type: 'EXCLUSIVE'
}, async (transaction) => {
await queryInterface.removeColumn('Devices', 'lastConnectivity', { transaction })
await queryInterface.removeColumn('Devices', 'notSeenForLongTime', { transaction })
await queryInterface.removeColumn('Devices', 'didDeviceReportUninstall', { transaction })
await queryInterface.dropTable('OldDevices', { transaction })
})
}
@@ -0,0 +1,35 @@
/*
* 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 { QueryInterface, Sequelize } from 'sequelize'
import { attributes as mailLoginTokenAttributes } from '../../maillogintoken'
export async function up (queryInterface: QueryInterface, sequelize: Sequelize) {
await sequelize.transaction({
type: 'EXCLUSIVE'
}, async (transaction) => {
await queryInterface.createTable('MailLoginTokens', mailLoginTokenAttributes, { transaction })
})
}
export async function down (queryInterface: QueryInterface, sequelize: Sequelize) {
await sequelize.transaction({
type: 'EXCLUSIVE'
}, async (transaction) => {
await queryInterface.dropTable('MailLoginTokens', { transaction })
})
}
@@ -0,0 +1,39 @@
/*
* 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 { QueryInterface, Sequelize } from 'sequelize'
import { attributesVersion3 } from '../../device'
export async function up (queryInterface: QueryInterface, sequelize: Sequelize) {
await sequelize.transaction({
type: 'EXCLUSIVE'
}, async (transaction) => {
await queryInterface.addColumn('Devices', 'isUserKeptSignedIn', {
...attributesVersion3.isUserKeptSignedIn
}, {
transaction
})
})
}
export async function down (queryInterface: QueryInterface, sequelize: Sequelize) {
await sequelize.transaction({
type: 'EXCLUSIVE'
}, async (transaction) => {
await queryInterface.removeColumn('Devices', 'isUserKeptSignedIn', { transaction })
})
}
@@ -0,0 +1,39 @@
/*
* 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 { QueryInterface, Sequelize } from 'sequelize'
import { attributesVersion2 } from '../../user'
export async function up (queryInterface: QueryInterface, sequelize: Sequelize) {
await sequelize.transaction({
type: 'EXCLUSIVE'
}, async (transaction) => {
await queryInterface.addColumn('Users', 'categoryForNotAssignedApps', {
...attributesVersion2.categoryForNotAssignedApps
}, {
transaction
})
})
}
export async function down (queryInterface: QueryInterface, sequelize: Sequelize) {
await sequelize.transaction({
type: 'EXCLUSIVE'
}, async (transaction) => {
await queryInterface.removeColumn('Users', 'categoryForNotAssignedApps', { transaction })
})
}
@@ -0,0 +1,39 @@
/*
* 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 { QueryInterface, Sequelize } from 'sequelize'
import { attributesVersion2 } from '../../category'
export async function up (queryInterface: QueryInterface, sequelize: Sequelize) {
await sequelize.transaction({
type: 'EXCLUSIVE'
}, async (transaction) => {
await queryInterface.addColumn('Categories', 'parentCategoryId', {
...attributesVersion2.parentCategoryId
}, {
transaction
})
})
}
export async function down (queryInterface: QueryInterface, sequelize: Sequelize) {
await sequelize.transaction({
type: 'EXCLUSIVE'
}, async (transaction) => {
await queryInterface.removeColumn('Categories', 'parentCategoryId', { transaction })
})
}
@@ -0,0 +1,39 @@
/*
* 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 { QueryInterface, Sequelize } from 'sequelize'
import { attributesVersion4 } from '../../device'
export async function up (queryInterface: QueryInterface, sequelize: Sequelize) {
await sequelize.transaction({
type: 'EXCLUSIVE'
}, async (transaction) => {
await queryInterface.addColumn('Devices', 'showDeviceConnected', {
...attributesVersion4.showDeviceConnected
}, {
transaction
})
})
}
export async function down (queryInterface: QueryInterface, sequelize: Sequelize) {
await sequelize.transaction({
type: 'EXCLUSIVE'
}, async (transaction) => {
await queryInterface.removeColumn('Devices', 'showDeviceConnected', { transaction })
})
}
@@ -0,0 +1,42 @@
/*
* 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 { QueryInterface, Sequelize } from 'sequelize'
import { attributesVersion2 } from '../../usedtime'
export async function up (queryInterface: QueryInterface, sequelize: Sequelize) {
await sequelize.transaction({
type: 'EXCLUSIVE'
}, async (transaction) => {
await queryInterface.addColumn('UsedTimes', 'lastUpdate', {
...attributesVersion2.lastUpdate
}, {
transaction
})
})
await queryInterface.addIndex('UsedTimes', ['lastUpdate'])
}
export async function down (queryInterface: QueryInterface, sequelize: Sequelize) {
await sequelize.transaction({
type: 'EXCLUSIVE'
}, async (transaction) => {
await queryInterface.removeIndex('UsedTimes', ['lastUpdate'], { transaction })
await queryInterface.removeColumn('UsedTimes', 'lastUpdate', { transaction })
})
}
@@ -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 { QueryInterface, Sequelize } from 'sequelize'
import { attributesVersion5 as deviceAttributes } from '../../device'
import { attributesVersion3 as userAttributes } from '../../user'
export async function up (queryInterface: QueryInterface, sequelize: Sequelize) {
await sequelize.transaction({
type: 'EXCLUSIVE'
}, async (transaction) => {
// users
await queryInterface.addColumn('Users', 'relaxPrimaryDeviceRule', {
...userAttributes.relaxPrimaryDeviceRule
}, { transaction })
// devices
await queryInterface.addColumn('Devices', 'defaultUserId', {
...deviceAttributes.defaultUserId
}, { transaction })
await queryInterface.addColumn('Devices', 'defaultUserTimeout', {
...deviceAttributes.defaultUserTimeout
}, { transaction })
})
}
export async function down (queryInterface: QueryInterface, sequelize: Sequelize) {
await sequelize.transaction({
type: 'EXCLUSIVE'
}, async (transaction) => {
// users
await queryInterface.removeColumn('Users', 'relaxPrimaryDeviceRule', { transaction })
// devices
await queryInterface.removeColumn('Devices', 'defaultUserId', { transaction })
await queryInterface.removeColumn('Devices', 'defaultUserTimeout', { transaction })
})
}
@@ -0,0 +1,46 @@
/*
* 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 { QueryInterface, Sequelize } from 'sequelize'
import { attributesVersion6 } from '../../device'
export async function up (queryInterface: QueryInterface, sequelize: Sequelize) {
await sequelize.transaction({
type: 'EXCLUSIVE'
}, async (transaction) => {
await queryInterface.addColumn('Devices', 'considerRebootManipulation', {
...attributesVersion6.considerRebootManipulation
}, {
transaction
})
await queryInterface.addColumn('Devices', 'didReboot', {
...attributesVersion6.didReboot
}, {
transaction
})
})
}
export async function down (queryInterface: QueryInterface, sequelize: Sequelize) {
await sequelize.transaction({
type: 'EXCLUSIVE'
}, async (transaction) => {
await queryInterface.removeColumn('Devices', 'considerRebootManipulation', { transaction })
await queryInterface.removeColumn('Devices', 'didReboot', { transaction })
})
}
@@ -0,0 +1,37 @@
/*
* 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 { QueryInterface, Sequelize } from 'sequelize'
import { attributesVersion4 as userAttributes } from '../../user'
export async function up (queryInterface: QueryInterface, sequelize: Sequelize) {
await sequelize.transaction({
type: 'EXCLUSIVE'
}, async (transaction) => {
await queryInterface.addColumn('Users', 'mailNotificationFlags', {
...userAttributes.mailNotificationFlags
}, { transaction })
})
}
export async function down (queryInterface: QueryInterface, sequelize: Sequelize) {
await sequelize.transaction({
type: 'EXCLUSIVE'
}, async (transaction) => {
await queryInterface.removeColumn('Users', 'mailNotificationFlags', { transaction })
})
}
+34
View File
@@ -0,0 +1,34 @@
/*
* 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 { resolve } from 'path'
import { Sequelize } from 'sequelize'
import * as Umzug from 'umzug'
export const createUmzug = (sequelize: Sequelize) => (
new Umzug({
storage: 'sequelize',
storageOptions: {
sequelize
},
migrations: {
params: [sequelize.getQueryInterface(), sequelize],
path: resolve(__dirname, '../../../build/database/migration/migrations'),
pattern: /^\d+[\w-]+\.js$/
}
})
)
+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 * as Sequelize from 'sequelize'
import { authTokenColumn } from './columns'
import { SequelizeAttributes } from './types'
export interface OldDeviceAttributes {
deviceAuthToken: string
}
export type OldDeviceInstance = Sequelize.Instance<OldDeviceAttributes> & OldDeviceAttributes
export type OldDeviceModel = Sequelize.Model<OldDeviceInstance, OldDeviceAttributes>
export const attributes: SequelizeAttributes<OldDeviceAttributes> = {
deviceAuthToken: {
...authTokenColumn,
primaryKey: true
}
}
export const createOldDeviceModel = (sequelize: Sequelize.Sequelize): OldDeviceModel => sequelize.define<OldDeviceInstance, OldDeviceAttributes>('OldDevice', attributes)
+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 * as Sequelize from 'sequelize'
import { createEnumColumn, familyIdColumn, timestampColumn } from './columns'
import { SequelizeAttributes } from './types'
export interface PurchaseAttributes {
familyId: string
service: 'googleplay'
transactionId: string
type: 'month' | 'year'
loggedAt: string
previousFullVersionEndTime: string
newFullVersionEndTime: string
}
export type PurchaseInstance = Sequelize.Instance<PurchaseAttributes> & PurchaseAttributes
export type PurchaseModel = Sequelize.Model<PurchaseInstance, PurchaseAttributes>
export const attributes: SequelizeAttributes<PurchaseAttributes> = {
familyId: { ...familyIdColumn },
service: {
...createEnumColumn(['googleplay']),
primaryKey: true
},
transactionId: {
type: Sequelize.STRING,
primaryKey: true
},
type: createEnumColumn(['month', 'year']),
loggedAt: timestampColumn,
previousFullVersionEndTime: timestampColumn,
newFullVersionEndTime: timestampColumn
}
export const createPurchaseModel = (sequelize: Sequelize.Sequelize): PurchaseModel => sequelize.define<PurchaseInstance, PurchaseAttributes>('Purchase', attributes)
+62
View File
@@ -0,0 +1,62 @@
/*
* 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 * as Sequelize from 'sequelize'
import { booleanColumn, familyIdColumn, idWithinFamilyColumn } from './columns'
import { SequelizeAttributes } from './types'
export interface TimelimitRuleAttributes {
familyId: string
ruleId: string
categoryId: string
applyToExtraTimeUsage: boolean
dayMaskAsBitmask: number
maximumTimeInMillis: number
}
export type TimelimitRuleInstance = Sequelize.Instance<TimelimitRuleAttributes> & TimelimitRuleAttributes
export type TimelimitRuleModel = Sequelize.Model<TimelimitRuleInstance, TimelimitRuleAttributes>
export const attributes: SequelizeAttributes<TimelimitRuleAttributes> = {
familyId: {
...familyIdColumn,
primaryKey: true
},
ruleId: {
...idWithinFamilyColumn,
primaryKey: true
},
categoryId: { ...idWithinFamilyColumn },
applyToExtraTimeUsage: { ...booleanColumn },
dayMaskAsBitmask: {
type: Sequelize.TINYINT,
allowNull: false,
validate: {
min: 0,
max: 1 | 2 | 4 | 8 | 16 | 32 | 64
}
},
maximumTimeInMillis: {
type: Sequelize.INTEGER,
allowNull: false,
validate: {
min: 0
}
}
}
export const createTimelimitRuleModel = (sequelize: Sequelize.Sequelize): TimelimitRuleModel => sequelize.define<TimelimitRuleInstance, TimelimitRuleAttributes>('TimelimitRule', attributes)
+22
View File
@@ -0,0 +1,22 @@
/*
* 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 * as Sequelize from 'sequelize'
export type SequelizeAttributes<T extends { [key: string]: any }> = {
[P in keyof T]: Sequelize.DefineAttributeColumnOptions;
}
+76
View File
@@ -0,0 +1,76 @@
/*
* 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 * as Sequelize from 'sequelize'
import { familyIdColumn, idWithinFamilyColumn, timestampColumn } from './columns'
import { SequelizeAttributes } from './types'
export interface UsedTimeAttributesVersion1 {
familyId: string
categoryId: string
dayOfEpoch: number
usedTime: number
}
export interface UsedTimeAttributesVersion2 {
lastUpdate: string
}
export type UsedTimeAttributes = UsedTimeAttributesVersion1 & UsedTimeAttributesVersion2
export type UsedTimeInstance = Sequelize.Instance<UsedTimeAttributes> & UsedTimeAttributes
export type UsedTimeModel = Sequelize.Model<UsedTimeInstance, UsedTimeAttributes>
export const attributesVersion1: SequelizeAttributes<UsedTimeAttributesVersion1> = {
familyId: {
...familyIdColumn,
primaryKey: true
},
categoryId: {
...idWithinFamilyColumn,
primaryKey: true
},
dayOfEpoch: {
type: Sequelize.INTEGER,
allowNull: false,
validate: {
min: 0
},
primaryKey: true
},
usedTime: {
type: Sequelize.INTEGER,
allowNull: false,
validate: {
min: 0
}
}
}
export const attributesVersion2: SequelizeAttributes<UsedTimeAttributesVersion2> = {
lastUpdate: {
...timestampColumn,
defaultValue: 0
}
}
export const attributes = {
...attributesVersion1,
...attributesVersion2
}
export const createUsedTimeModel = (sequelize: Sequelize.Sequelize): UsedTimeModel => sequelize.define<UsedTimeInstance, UsedTimeAttributes>('UsedTime', attributes)
+131
View File
@@ -0,0 +1,131 @@
/*
* 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 * as Sequelize from 'sequelize'
import { optionalPasswordRegex, optionalSaltRegex } from '../util/password'
import { booleanColumn, createEnumColumn, familyIdColumn, idWithinFamilyColumn, labelColumn, optionalIdWithinFamilyColumn, timestampColumn } from './columns'
import { SequelizeAttributes } from './types'
export interface UserAttributesVersion1 {
familyId: string
userId: string
name: string
passwordHash: string
secondPasswordHash: string
secondPasswordSalt: string
type: 'parent' | 'child'
mail: string
timeZone: string
disableTimelimitsUntil: string
// empty = unset; can contain an invalid device id or the id of an device which is not used by this user
// in this case, it should be treated like unset
currentDevice: string
}
export interface UserAttributesVersion2 {
categoryForNotAssignedApps: string
}
export interface UserAttributesVersion3 {
relaxPrimaryDeviceRule: boolean
}
export interface UserAttributesVersion4 {
// 1: manipulation warnings
mailNotificationFlags: number
}
export type UserAttributes = UserAttributesVersion1 & UserAttributesVersion2 &
UserAttributesVersion3 & UserAttributesVersion4
export type UserInstance = Sequelize.Instance<UserAttributes> & UserAttributes
export type UserModel = Sequelize.Model<UserInstance, UserAttributes>
export const attributesVersion1: SequelizeAttributes<UserAttributesVersion1> = {
familyId: {
...familyIdColumn,
primaryKey: true
},
userId: {
...idWithinFamilyColumn,
primaryKey: true
},
name: { ...labelColumn },
passwordHash: {
type: Sequelize.STRING,
allowNull: false,
validate: {
is: optionalPasswordRegex
}
},
secondPasswordHash: {
type: Sequelize.STRING,
allowNull: false,
validate: {
is: optionalPasswordRegex
}
},
secondPasswordSalt: {
type: Sequelize.STRING,
allowNull: false,
validate: {
is: optionalSaltRegex
}
},
type: createEnumColumn(['parent', 'child']),
mail: {
type: Sequelize.STRING,
allowNull: false
},
timeZone: { ...labelColumn },
disableTimelimitsUntil: { ...timestampColumn },
currentDevice: { ...optionalIdWithinFamilyColumn }
}
export const attributesVersion2: SequelizeAttributes<UserAttributesVersion2> = {
categoryForNotAssignedApps: {
...optionalIdWithinFamilyColumn,
defaultValue: ''
}
}
export const attributesVersion3: SequelizeAttributes<UserAttributesVersion3> = {
relaxPrimaryDeviceRule: {
...booleanColumn,
defaultValue: false
}
}
export const attributesVersion4: SequelizeAttributes<UserAttributesVersion4> = {
mailNotificationFlags: {
type: Sequelize.INTEGER,
defaultValue: 0,
validate: {
min: 0,
max: 1
}
}
}
export const attributes: SequelizeAttributes<UserAttributes> = {
...attributesVersion1,
...attributesVersion2,
...attributesVersion3,
...attributesVersion4
}
export const createUserModel = (sequelize: Sequelize.Sequelize): UserModel => sequelize.define<UserInstance, UserAttributes>('User', attributes)