From 3bacf55ea0cbced8bb4be8be3d631aa513abad50 Mon Sep 17 00:00:00 2001 From: BitK Date: Tue, 30 Nov 2021 02:42:38 +0100 Subject: [PATCH 01/43] Update format command to handle subdirectory Only the files in /src where formated with `yarn format` now the subfolder are also formated. + formating importCtf and savepointWrapper --- api/package.json | 2 +- api/src/plugins/importCtf.ts | 140 ++++++++++++++-------------- api/src/plugins/savepointWrapper.ts | 29 +++--- 3 files changed, 89 insertions(+), 82 deletions(-) diff --git a/api/package.json b/api/package.json index 45da6a043..e1084eb97 100644 --- a/api/package.json +++ b/api/package.json @@ -8,7 +8,7 @@ "start": "NODE_ENV=production node dist/index.js", "build": "tsc", "lint": "eslint --fix 'src/**/*.ts'", - "format": "prettier --write 'src/*.ts'", + "format": "prettier --write 'src/**/*.ts'", "dev": "NODE_ENV=development nodemon src/index.ts", "dev:migrate": "DATABASE_URL= yarn run db-migrate -e dev up" }, diff --git a/api/src/plugins/importCtf.ts b/api/src/plugins/importCtf.ts index 55486059a..ed66ec5ca 100644 --- a/api/src/plugins/importCtf.ts +++ b/api/src/plugins/importCtf.ts @@ -1,54 +1,57 @@ - import { makeExtendSchemaPlugin, gql } from "graphile-utils"; -import axios from "axios" -import savepointWrapper from "./savepointWrapper" +import axios from "axios"; +import savepointWrapper from "./savepointWrapper"; interface CTFTimeResponse { - title: string; - weight: number; - url: string, - logo: string, - ctftime_url: string, - description: string, - start: string, - finish: string + title: string; + weight: number; + url: string; + logo: string; + ctftime_url: string; + description: string; + start: string; + finish: string; } - async function fetchFromCtftime(id: number): Promise { - const url = `https://ctftime.org/api/v1/events/${id}/`; - const response = await axios.get(url, { - headers: { "User-Agent": "CTFNote" }, // The default axios user-agent is blacklisted by ctftime :/ - }); - return response.data + const url = `https://ctftime.org/api/v1/events/${id}/`; + const response = await axios.get(url, { + headers: { "User-Agent": "CTFNote" }, // The default axios user-agent is blacklisted by ctftime :/ + }); + return response.data; } +export default makeExtendSchemaPlugin((build) => { + const { pgSql: sql } = build; + return { + typeDefs: gql` + input ImportCtfInput { + ctftimeId: Int! + } -export default makeExtendSchemaPlugin(build => { - const { pgSql: sql } = build; - return { - typeDefs: gql` - - input ImportCtfInput { - ctftimeId: Int! - } - - type ImportCtfPayload { - ctf: Ctf @pgField - query: Query - } + type ImportCtfPayload { + ctf: Ctf @pgField + query: Query + } - extend type Mutation { - importCtf(input: ImportCtfInput) : ImportCtfPayload - } - `, - resolvers: { - Mutation: { - importCtf: async (_query, { input: { ctftimeId } }, { pgClient }, resolveInfo) => { - const ctf = await fetchFromCtftime(ctftimeId) - await savepointWrapper(pgClient, async () => { - const { rows: [newCtf] } = await pgClient.query( - `INSERT INTO ctfnote.ctf( + extend type Mutation { + importCtf(input: ImportCtfInput): ImportCtfPayload + } + `, + resolvers: { + Mutation: { + importCtf: async ( + _query, + { input: { ctftimeId } }, + { pgClient }, + resolveInfo + ) => { + const ctf = await fetchFromCtftime(ctftimeId); + await savepointWrapper(pgClient, async () => { + const { + rows: [newCtf], + } = await pgClient.query( + `INSERT INTO ctfnote.ctf( title, weight, ctf_url, @@ -60,32 +63,33 @@ export default makeExtendSchemaPlugin(build => { ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING *; `, - [ - ctf.title, - ctf.weight, - ctf.url, - ctf.logo, - ctf.ctftime_url, - ctf.description, - ctf.start, - ctf.finish, - ] - ) - const [row] = await resolveInfo.graphile.selectGraphQLResultFromTable( - sql.fragment`ctfnote.ctf`, - (tableAlias, queryBuilder) => { - queryBuilder.where( - sql.fragment`${tableAlias}.id = ${sql.value(newCtf.id)}` - ); - } - ) - return { - data: row, - query: build.$$isQuery, - }; - }) - }, - }, + [ + ctf.title, + ctf.weight, + ctf.url, + ctf.logo, + ctf.ctftime_url, + ctf.description, + ctf.start, + ctf.finish, + ] + ); + const [row] = + await resolveInfo.graphile.selectGraphQLResultFromTable( + sql.fragment`ctfnote.ctf`, + (tableAlias, queryBuilder) => { + queryBuilder.where( + sql.fragment`${tableAlias}.id = ${sql.value(newCtf.id)}` + ); + } + ); + return { + data: row, + query: build.$$isQuery, + }; + }); }, - }; + }, + }, + }; }); diff --git a/api/src/plugins/savepointWrapper.ts b/api/src/plugins/savepointWrapper.ts index fbf5e1927..9eeb696bb 100644 --- a/api/src/plugins/savepointWrapper.ts +++ b/api/src/plugins/savepointWrapper.ts @@ -1,16 +1,19 @@ -import { Client } from "pg" +import { Client } from "pg"; -async function savepointWrapper(pgClient: Client, f: () => void): Promise { - const name = `"CHECKPOINT-${Math.floor(Math.random() * 0xffff)}"` - await pgClient.query(`SAVEPOINT ${name}`); - try { - await f() - } catch (e) { - await pgClient.query(`ROLLBACK TO SAVEPOINT ${name}`); - throw e; - } finally { - await pgClient.query(`RELEASE SAVEPOINT ${name}`); - } +async function savepointWrapper( + pgClient: Client, + f: () => void +): Promise { + const name = `"CHECKPOINT-${Math.floor(Math.random() * 0xffff)}"`; + await pgClient.query(`SAVEPOINT ${name}`); + try { + await f(); + } catch (e) { + await pgClient.query(`ROLLBACK TO SAVEPOINT ${name}`); + throw e; + } finally { + await pgClient.query(`RELEASE SAVEPOINT ${name}`); + } } -export default savepointWrapper; \ No newline at end of file +export default savepointWrapper; From ece1bf94eeeac586a3ef02272544cae9b3aa227a Mon Sep 17 00:00:00 2001 From: BitK Date: Tue, 30 Nov 2021 02:43:08 +0100 Subject: [PATCH 02/43] removed useless parameters --- api/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/index.ts b/api/src/index.ts index 100d30619..d7ab7f825 100644 --- a/api/src/index.ts +++ b/api/src/index.ts @@ -70,7 +70,7 @@ function createApp(postgraphileOptions: PostGraphileOptions) { app.use( "/uploads", express.static("uploads", { - setHeaders: function (res, path, stat) { + setHeaders: function (res) { res.set("Content-Disposition", "attachment"); }, }) From cd9382ddf7706ae3b3a2d6fd89ed22c5f5c7a56a Mon Sep 17 00:00:00 2001 From: BitK Date: Tue, 30 Nov 2021 02:46:11 +0100 Subject: [PATCH 03/43] Format front --- front/src/components/CTF/Guests.vue | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/front/src/components/CTF/Guests.vue b/front/src/components/CTF/Guests.vue index 5322675eb..8d5c2e80a 100644 --- a/front/src/components/CTF/Guests.vue +++ b/front/src/components/CTF/Guests.vue @@ -58,7 +58,11 @@ export default defineComponent({ }, computed: { guests() { - return this.team.filter((p) => p.role == Role.UserGuest || (p.role == Role.UserFriend && this.ctf.endTime > this.now)); + return this.team.filter( + (p) => + p.role == Role.UserGuest || + (p.role == Role.UserFriend && this.ctf.endTime > this.now) + ); }, guestsWithInvitation() { return this.guests.map((g) => { From 5d73f7b83cd9d6decfa1e27aea07522647f790ba Mon Sep 17 00:00:00 2001 From: JJ-8 <2482444-JJ-8@users.noreply.gitlab.com> Date: Sat, 4 Dec 2021 12:54:37 +0100 Subject: [PATCH 04/43] Add word wrapping to table layout This prevents lots of vertical scrolling when there is a long description. Related to https://github.com/TFNS/CTFNote/issues/111 --- front/src/components/Task/TaskTable.vue | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/front/src/components/Task/TaskTable.vue b/front/src/components/Task/TaskTable.vue index a99e1ef31..620ed70a1 100644 --- a/front/src/components/Task/TaskTable.vue +++ b/front/src/components/Task/TaskTable.vue @@ -9,7 +9,7 @@