diff --git a/sql/tasks/hasNext.sql b/sql/tasks/hasNext.sql deleted file mode 100644 index dfaa571..0000000 --- a/sql/tasks/hasNext.sql +++ /dev/null @@ -1 +0,0 @@ -SELECT COUNT(*) > 0 r FROM "tasks" WHERE owner = $1 AND "id" > $2; \ No newline at end of file diff --git a/sql/tasks/hasPrev.sql b/sql/tasks/hasPrev.sql deleted file mode 100644 index d6f7690..0000000 --- a/sql/tasks/hasPrev.sql +++ /dev/null @@ -1 +0,0 @@ -SELECT COUNT(*) > 0 r FROM "tasks" WHERE owner = $1 AND "id" < $2; \ No newline at end of file diff --git a/sql/tasks/list.sql b/sql/tasks/list.sql index 8bb2ba8..fdf222d 100644 --- a/sql/tasks/list.sql +++ b/sql/tasks/list.sql @@ -1,14 +1,14 @@ + SELECT id, + owner, name, notes, schedule, - min_frequency, - max_frequency, created_at FROM tasks WHERE - owner = $1 AND ($2 IS NULL OR id > $2) AND ($3 IS NULL OR id < $3) -ORDER BY created_at ASC -LIMIT $4; + owner = $1 +ORDER BY created_at ASC, id ASC +LIMIT $2 OFFSET $3; diff --git a/sql/tasks/listReverse.sql b/sql/tasks/listReverse.sql deleted file mode 100644 index 2d1e01b..0000000 --- a/sql/tasks/listReverse.sql +++ /dev/null @@ -1,14 +0,0 @@ -SELECT - id, - name, - notes, - schedule, - min_frequency, - max_frequency, - created_at -FROM - tasks -WHERE - owner = $1 AND ($2 IS NULL OR id > $2) AND ($3 IS NULL OR id < $3) -ORDER BY created_at DESC -LIMIT $4; diff --git a/src/server/auth.ts b/src/server/auth.ts index cdecb5a..f93be40 100644 --- a/src/server/auth.ts +++ b/src/server/auth.ts @@ -40,10 +40,16 @@ export const authMiddleware: () => express.Handler = () => async ( next(); }; -export const requireAuthMiddleware: express.Handler = (req, res, next) => { +export const requireAuthMiddleware: (redirect?: string) => express.Handler = ( + redirect = null +) => (req, res, next) => { if (!req.user) { - next(createHttpError(401)); + if (redirect) { + res.redirect(redirect); + } else { + next(createHttpError(401)); + } + } else { + next(); } - - next(); }; diff --git a/src/server/db/models.ts b/src/server/db/models.ts index c5335fc..2e15080 100644 --- a/src/server/db/models.ts +++ b/src/server/db/models.ts @@ -39,9 +39,7 @@ export interface Task { owner: number; name: string; notes?: string; - schedule: ScheduleType; - minFrequency?: number; - maxFrequency?: number; + schedule: object; createdAt: DateTime; } diff --git a/src/server/db/repos/tasks.ts b/src/server/db/repos/tasks.ts index 2587efb..257309d 100644 --- a/src/server/db/repos/tasks.ts +++ b/src/server/db/repos/tasks.ts @@ -23,9 +23,7 @@ function rowToTask(row: any): Task { owner: +row.owner, name: row.name, notes: row.notes, - schedule: row.schedule as ScheduleType, - minFrequency: +row.minFrequency, - maxFrequency: +row.maxFrequency, + schedule: row.schedule, createdAt: row.created_at }; } @@ -40,32 +38,14 @@ export class TaskRepository { public async list( owner: number, limit?: number, - after?: number, - before?: number + offset?: number ): Promise { - return this.db.map(sql.list, [owner, after, before, limit || 10], row => + return this.db.map(sql.list, [owner, limit || 10, offset || 0], row => rowToTask(row) ); } - public async listReverse( - owner: number, - limit?: number, - after?: number, - before?: number - ): Promise { - return this.db.map( - sql.listReverse, - [owner, after, before, limit || 10], - row => rowToTask(row) - ); - } - - public async hasNext(owner: number, after: number): Promise { - return this.db.one(sql.hasNext, [owner, after]).then(row => row.r); - } - - public async hasPrev(owner: number, before: number): Promise { - return this.db.one(sql.hasPrev, [owner, before]).then(row => row.r); + public async count(owner: number): Promise { + return this.db.one(sql.count, [owner], row => +row.c); } } diff --git a/src/server/db/sql/index.ts b/src/server/db/sql/index.ts index 42a3f3e..f3da348 100644 --- a/src/server/db/sql/index.ts +++ b/src/server/db/sql/index.ts @@ -45,10 +45,7 @@ const users = { const tasks = { count: sql("tasks/count.sql"), - hasNext: sql("tasks/hasNext.sql"), - hasPrev: sql("tasks/hasPrev.sql"), - list: sql("tasks/list.sql"), - listReverse: sql("tasks/listReverse.sql") + list: sql("tasks/list.sql") }; const sessions = { diff --git a/src/server/routes/api.ts b/src/server/routes/api.ts new file mode 100644 index 0000000..04b443c --- /dev/null +++ b/src/server/routes/api.ts @@ -0,0 +1,57 @@ +// Copyright (C) 2019 ModZero +// +// 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, either version 3 of the +// License, or (at your option) any later version. +// +// 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 { requireAuthMiddleware } from "@kredens/server/auth"; +import { db } from "@kredens/server/db"; +import express from "express"; + +const router = express.Router(); + +function tryInt(v: string, def?: number): number | undefined { + if (v) { + const value = parseInt(v, 10); + return isNaN(value) ? def : value; + } + + return def; +} + +router.use(requireAuthMiddleware()); +router.get("/tasks", async (req, res, next) => { + const limit = tryInt(req.query.limit, 10); + const offset = tryInt(req.query.offset, 0); + + const result = await db.tx(async tx => { + const tasks = await tx.tasks.list(req.user.id, limit, offset); + const count = await tx.tasks.count(req.user.id); + return { + tasks, + count + }; + }); + + res.json({ + tasks: result.tasks.map(t => ({ + id: t.id, + name: t.name, + notes: t.notes, + schedule: t.schedule, + createdAt: t.createdAt.toISO + })), + count: result.count + }); +}); + +export default router; diff --git a/src/server/routes/index.ts b/src/server/routes/index.ts index d1b9294..55e969f 100644 --- a/src/server/routes/index.ts +++ b/src/server/routes/index.ts @@ -14,12 +14,14 @@ // along with this program. If not, see . import express from "express"; +import apiRouter from "./api"; import authRouter from "./auth"; import homeRouter from "./home"; const router = express.Router({ strict: true }); router.use("/auth$", authRouter); +router.use("/api/", apiRouter); router.use("/*", homeRouter); export default router;