diff --git a/backend/src/api/start.ts b/backend/src/api/start.ts index 7d046c12..b4eed63b 100644 --- a/backend/src/api/start.ts +++ b/backend/src/api/start.ts @@ -6,6 +6,7 @@ import { initAuth } from "./auth"; import { initDocs } from "./docs"; import { initGuildsAPI } from "./guilds"; import { clientError, error, notFound } from "./responses"; +import { startBackgroundTasks } from "./tasks"; const app = express(); @@ -47,3 +48,5 @@ app.use((req, res, next) => { const port = (process.env.PORT && parseInt(process.env.PORT, 10)) || 3000; app.listen(port, "0.0.0.0", () => console.log(`API server listening on port ${port}`)); // tslint:disable-line + +startBackgroundTasks(); diff --git a/backend/src/api/tasks.ts b/backend/src/api/tasks.ts new file mode 100644 index 00000000..6edf218d --- /dev/null +++ b/backend/src/api/tasks.ts @@ -0,0 +1,10 @@ +import { ApiPermissionAssignments } from "../data/ApiPermissionAssignments"; +import { MINUTES } from "../utils"; + +export function startBackgroundTasks() { + // Clear expired API permissions every minute + const apiPermissions = new ApiPermissionAssignments(); + setInterval(() => { + apiPermissions.clearExpiredPermissions(); + }, 1 * MINUTES); +} diff --git a/backend/src/data/ApiPermissionAssignments.ts b/backend/src/data/ApiPermissionAssignments.ts index 29686adc..fc04b61c 100644 --- a/backend/src/data/ApiPermissionAssignments.ts +++ b/backend/src/data/ApiPermissionAssignments.ts @@ -55,4 +55,12 @@ export class ApiPermissionAssignments extends BaseRepository { removeUser(guildId, userId) { return this.apiPermissions.delete({ guild_id: guildId, type: ApiPermissionTypes.User, target_id: userId }); } + + async clearExpiredPermissions() { + await this.apiPermissions + .createQueryBuilder() + .where("expires_at IS NOT NULL") + .andWhere("expires_at <= NOW()") + .delete(); + } } diff --git a/backend/src/data/entities/ApiPermissionAssignment.ts b/backend/src/data/entities/ApiPermissionAssignment.ts index fcea7595..454fe17c 100644 --- a/backend/src/data/entities/ApiPermissionAssignment.ts +++ b/backend/src/data/entities/ApiPermissionAssignment.ts @@ -18,6 +18,9 @@ export class ApiPermissionAssignment { @Column("simple-array") permissions: string[]; + @Column() + expires_at: string; + @ManyToOne( type => ApiUserInfo, userInfo => userInfo.permissionAssignments, diff --git a/backend/src/migrations/1630837386329-AddExpiresAtToApiPermissions.ts b/backend/src/migrations/1630837386329-AddExpiresAtToApiPermissions.ts new file mode 100644 index 00000000..3eb6ea27 --- /dev/null +++ b/backend/src/migrations/1630837386329-AddExpiresAtToApiPermissions.ts @@ -0,0 +1,18 @@ +import { MigrationInterface, QueryRunner, TableColumn } from "typeorm"; + +export class AddExpiresAtToApiPermissions1630837386329 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.addColumns("api_permissions", [ + new TableColumn({ + name: "expires_at", + type: "boolean", + isNullable: true, + default: null, + }), + ]); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropColumn("api_permissions", "expires_at"); + } +}