This commit is contained in:
2021-11-22 20:07:06 +01:00
parent ee29c0b25b
commit 1acc0d4244
17 changed files with 275 additions and 163 deletions

View File

@@ -2,17 +2,23 @@ import dj from 'dayjs'
import Dexie from 'dexie'
import RelativeTime from 'dayjs/plugin/relativeTime'
import Duration from 'dayjs/plugin/duration'
import Joi from 'joi'
import { checkForErrors, DBValidator } from './validation'
dj.extend(Duration)
dj.extend(RelativeTime)
export const DB = new Dexie('ora')
DB.version(2).stores({
logs: `++id, host, timestamp`,
limits: `++id, host`,
})
DB.version(3).stores({
settings: `key, value`,
})
export function normalizeTimestamp(timestamp) {
// Normalize every dato to 15 minutes
const t = dj(timestamp)
@@ -43,36 +49,8 @@ export async function dump() {
}
}
export function validate(data) {
const schema = Joi.object({
limits: Joi.array().items(
Joi.object({
host: Joi.string(),
id: Joi.number(),
rules: Joi.array().items(
Joi.object({
limit: Joi.array().items(Joi.string(), Joi.number()),
every: Joi.array().items(Joi.string(), Joi.number()),
})
),
})
),
logs: Joi.array().items(
Joi.object({
host: Joi.string(),
id: Joi.number(),
seconds: Joi.number(),
timestamp: Joi.string(),
})
),
})
const validated = schema.validate(data, { presence: 'required' })
return !validated.error
}
export async function load(data) {
if (!validate(data)) throw new Error('Invalid data')
if (!checkForErrors(DBValidator, data)) throw new Error('Invalid data')
await clear()
await DB.limits.bulkAdd(data.limits)
@@ -83,3 +61,8 @@ export async function load(data) {
}))
)
}
export async function updateOrSet(table, key, value) {
// const updated = await table.update(key, value)
// if(updated === 0) await table.
}

43
src/shared/validation.js Normal file
View File

@@ -0,0 +1,43 @@
import Joi from 'joi'
export const DurationTupleValidator = Joi.array().length(2).ordered(Joi.number(), Joi.string())
export const LimitValidator = Joi.object({
host: Joi.string().domain(),
id: Joi.number().optional(),
rules: Joi.array().items(
Joi.object({
limit: DurationTupleValidator,
every: DurationTupleValidator,
})
),
})
export const LogValidator = Joi.object({
host: Joi.string(),
id: Joi.number().optional(),
seconds: Joi.number(),
timestamp: Joi.date(),
})
export const SettingsValidator = Joi.object({
lastActivity: Joi.date()
.default(() => new Date())
.optional(), // Last user activity, to calculate idle time
retention: Joi.number().default(90).optional(), // Days to keep logs
idleTimeout: DurationTupleValidator.default(5).optional(), // Idle timeout in minutes
})
export const DBValidator = Joi.object({
limits: Joi.array().items(LimitValidator),
logs: Joi.array().items(LogValidator),
settings: SettingsValidator.optional(),
})
export function checkForErrors(validator, data) {
const validated = validator.validate(data, { presence: 'required' })
if (validated.error) {
console.error('Validation error', validated.error)
}
return validated.error
}