Skip to content

Commit 9fdd7bd

Browse files
authored
Merge pull request #49 from lactf/logger
Log failed flag attempts
2 parents af8fb15 + 8cce65f commit 9fdd7bd

4 files changed

Lines changed: 57 additions & 0 deletions

File tree

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
exports.up = function (pgm) {
2+
pgm.createTable('attempts', {
3+
id: { type: 'uuid', primaryKey: true },
4+
challengeid: { type: 'string', notNull: true },
5+
userid: { type: 'uuid', notNull: true },
6+
submission: { type: 'string', notNull: true },
7+
createdat: { type: 'timestamp', notNull: true }
8+
})
9+
}
10+
11+
exports.down = function (pgm) {
12+
pgm.dropTable('attempts')
13+
}

server/api/challs/submit.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ export default {
7171
}]
7272
}
7373

74+
await db.attempts.newAttempt({ id: uuidv4(), challengeid, userid: uuid, submission: submittedFlag, createdat: new Date() })
75+
7476
const bufSubmittedFlag = Buffer.from(submittedFlag)
7577
const bufCorrectFlag = Buffer.from(challenge.flag)
7678

server/database/attempts.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import db from './db'
2+
import { Challenge } from '../challenges/types'
3+
import { User } from './users'
4+
import { ExtractQueryType } from './util'
5+
6+
export interface Attempt {
7+
id: string;
8+
challengeid: Challenge['id'];
9+
userid: User['id'];
10+
submission: string;
11+
createdat: Date;
12+
}
13+
14+
export const getAllAttempts = (): Promise<Attempt[]> => {
15+
return db.query<Attempt>('SELECT * FROM attempts ORDER BY createdat ASC')
16+
.then(res => res.rows)
17+
}
18+
19+
export const getAttemptsByUserId = ({ userid }: Pick<Attempt, 'userid'>): Promise<Attempt[]> => {
20+
return db.query<Attempt>('SELECT * FROM attempts WHERE userid = $1 ORDER BY createdat DESC', [userid])
21+
.then(res => res.rows)
22+
}
23+
24+
export const getAttemptsByChallId = ({ challengeid, limit, offset }: Pick<Attempt, 'challengeid'> & { limit: number; offset: number; }): Promise<(Attempt & Pick<User, 'name'>)[]> => {
25+
return db.query<ExtractQueryType<typeof getAttemptsByChallId>>('SELECT attempts.id, attempts.userid, attempts.submissions, attempts.createdat, users.name FROM attempts INNER JOIN users ON attempts.userid = users.id WHERE attempts.challengeid=$1 ORDER BY attempts.createdat ASC LIMIT $2 OFFSET $3', [challengeid, limit, offset])
26+
.then(res => res.rows)
27+
}
28+
29+
export const getAttemptByUserIdAndChallId = ({ userid, challengeid }: Pick<Attempt, 'userid' | 'challengeid'>): Promise<Attempt | undefined> => {
30+
return db.query<Attempt>('SELECT * FROM attempts WHERE userid = $1 AND challengeid = $2 ORDER BY createdat DESC', [userid, challengeid])
31+
.then(res => res.rows[0])
32+
}
33+
34+
export const newAttempt = ({ id, userid, challengeid, submission, createdat }: Attempt): Promise<Attempt> => {
35+
return db.query<Attempt>('INSERT INTO attempts (id, challengeid, userid, submission, createdat) VALUES ($1, $2, $3, $4, $5) RETURNING *', [id, challengeid, userid, submission, createdat])
36+
.then(res => res.rows[0])
37+
}
38+
39+
export const removeAttemptsByUserId = async ({ userid }: Pick<Attempt, 'userid'>): Promise<void> => {
40+
await db.query('DELETE FROM attempts WHERE userid = $1', [userid])
41+
}

server/database/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export * as solves from './solves'
2+
export * as attempts from './attempts'
23
export * as users from './users'
34
export * as members from './members'
45
export * as challenges from './challenges'

0 commit comments

Comments
 (0)