Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
3bacf55
Update format command to handle subdirectory
Nov 30, 2021
ece1bf9
removed useless parameters
Nov 30, 2021
aaf9b83
Merge branch 'dev' of github.com:TFNS/CTFNote into dev
Nov 30, 2021
cd9382d
Format front
Nov 30, 2021
5d73f7b
Add word wrapping to table layout
Dec 4, 2021
e76e646
Base search migrations & front dialog
SakiiR Dec 16, 2021
4919d54
First version
SakiiR Dec 17, 2021
d932aa5
Dialog style and width
SakiiR Dec 17, 2021
866db6a
Added keyboard shortcut hint
SakiiR Dec 17, 2021
ef5449c
Handle CTRL-N & CTRL-P to cycle through search results
SakiiR Dec 20, 2021
7151e36
Now using the "postgraphile-plugin-connection-filter".
SakiiR Jan 10, 2022
9641fb8
Update format command to handle subdirectory
Nov 30, 2021
0c10d83
removed useless parameters
Nov 30, 2021
1c7b233
Format front
Nov 30, 2021
655fc48
#127 - Disable CSP for the dev version of hedgedoc
SakiiR Dec 16, 2021
f99c6f6
Initial contribution guide ( open to review/change)
SakiiR Dec 20, 2021
d3115d5
undo formating
SakiiR Dec 20, 2021
d44be2b
Initiate the pad with task information (title, description and category)
SakiiR Dec 20, 2021
47ff200
removing changes from 0-contribution-guide branch
SakiiR Dec 20, 2021
63e0de7
Fixed description/category being undefined in the note
SakiiR Dec 21, 2021
669ecf6
Fixed the layout
SakiiR Dec 21, 2021
5e8d16b
Moved the separator
SakiiR Dec 22, 2021
c22625a
formated
SakiiR Dec 22, 2021
b3fc996
Front: upgrade nginx to 1.21.5
XeR Dec 30, 2021
829de36
Initial contribution guide ( open to review/change)
SakiiR Dec 20, 2021
ff94a73
Git hooks instruction
SakiiR Dec 20, 2021
c937f67
Moved the "Git" part on top of the document
SakiiR Dec 21, 2021
71485c5
Moderators/Developpers -> Collaborators
SakiiR Jan 10, 2022
7cf642d
Front: update dependencies
XeR Jan 31, 2022
aae0fbe
API: update dependencies
XeR Jan 31, 2022
31254fe
Front: add vue and router
XeR Jan 31, 2022
ec30302
Front: upgrade nginx to 1.21.6
XeR Jan 31, 2022
11454ef
Added 39-sort-users.sql in order to merge on dev
SakiiR Mar 30, 2022
5da8b8f
Merge branch 'dev' into 80-search-task-n-ctf
SakiiR Mar 30, 2022
cf4c2e1
Added a composable for the search ctf and task dialog
SakiiR Mar 31, 2022
0d49a58
Better shortcut name
SakiiR Mar 31, 2022
45a87ed
fixed bug
SakiiR Mar 31, 2022
39f2456
Limit task creation by access controll
JJ-8 Apr 2, 2022
efb8156
Merge branch 'dev' into create-task-access-control
JJ-8 Apr 2, 2022
4601d9b
Avoid error on empty selection
SakiiR Apr 4, 2022
fbab379
Added insensitive search for ctfs/tasks
SakiiR Apr 4, 2022
b247c38
Added security restrictions on the new connection filter postgraphile…
SakiiR Apr 4, 2022
b3a9cb2
Merge pull request #154 from JJ-8/create-task-access-control
JJ-8 Apr 5, 2022
5a21615
Remove `!important`
JJ-8 Apr 5, 2022
43b2f56
Merge pull request #148 from JJ-8/table-wrapping
JJ-8 Apr 5, 2022
f77e294
Fixed hint for search input
SakiiR Apr 5, 2022
bf6f677
Merge pull request #129 from SakiiR/80-search-task-n-ctf
JJ-8 Apr 7, 2022
f62680e
Update yarn lock file
JJ-8 Apr 9, 2022
c055d3e
Update Hedgedoc to 1.9.3
JJ-8 Apr 14, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 92 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# CTFNote - Contribution Guide

When contributing to this repository, please first discuss the change you wish to make via issue with the collaborators of this repository before making a change.

## Git process

In order to push new code on this repository, you first have to create a new fork within your github workspace.

Once your fork is created (`https://github.com/<your_username>/CTFNote`), you can create a new branch starting with the associated issue number in the name and start working on it.

> If you start from scratch and no issues are associated with your changes, you can create a branch starting with '0-'.

```shell
$ git checkout -b <issue-number>-<branch-name>
```

Examples of branch name:

- `132-add-new-feature`
- `343-add-past-ctf-role`
- `13-fix-bug-in-password-reset`
- `37-leak-flag-to-TFNS`
- `0-contribution-guide`

Once you think the job is done, issue the pull request and target the **dev** branch of the official CTFNote repository.

You can also create the pull request before finishing the job but don't forget to add "WiP: " as a suffix in the title to let the collaborators know you are still working on the request.

## Deploying the dev version

### Prerequisites

- [Install docker](https://docs.docker.com/get-docker/)
- [Install yarn](https://classic.yarnpkg.com/lang/en/docs/install/)

### Install the git hooks

Go at the root folder and install the dependencies and install the git hooks:

```shell
$ yarn
```

This should run the prepare script and install the linting pre-commit hooks:

```
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 🔨 Building fresh packages...
$ husky install
[##] 2/2husky - Git hooks installed
✨ Done in 0.40s.
```

### Start the third party containers

```shell
$ docker compose \
-f docker-compose.dev.yml \
up -d hedgedoc db adminer
```

### Start the API

```shell
$ cd api
api/ $ yarn # Install the dependencies
api/ $ yarn dev # Run the dev version (hot reloading included)
```

### Start the Front

```shell
$ cd front
front/ $ yarn # Install the dependencies
front/ $ yarn dev # Run the dev version (hot reloading included)
```

### Exposed endpoints

The following endpoint are exposed and can be used in the developpement environment

- [API](http://localhost:3000/)
- [GraphiQL](http://localhost:3000/graphiql)
- [Hedgedoc](http://localhost:3001/)
- [Quasar APP](http://localhost:8088/)
- [Adminer](http://localhost:3002/?pgsql=db&username=ctfnote&db=ctfnote)

## Review

To merge a pull request, two distinct reviews from two different collaborators are required.
37 changes: 27 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
[![CTFNote logo](screenshots/logo_small.webp)](screenshots/logo.png)

# CTFNote

## Introduction

CTFNote is a collaborative tool aiming to help CTF teams to organise their work.

[![Screenshot of the task list](screenshots/task_small.webp)](screenshots/task.png)


## Installation

Before starting, make sure to fill in the information in the `.env` file.
Expand Down Expand Up @@ -52,12 +53,14 @@ server {

Edit the `docker-compose.yml` file to make sure CTFNote only listens on
localhost:

```diff
- - 8080:80
+ - 127.0.0.1:8080:80
```

Edit the `.env` file to instruct the pad to use TLS:

```diff
# Secure: we're using HTTPS
-# CMD_PROTOCOL_USESSL=true
Expand All @@ -68,48 +71,52 @@ Edit the `.env` file to instruct the pad to use TLS:
+CMD_DOMAIN=example.org:1337
```

After deploying this configuration, run `certbot` to make it available over HTTPS.
After deploying this configuration, run `certbot` to make it available over HTTPS.
See [this article](https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-20-04) for more information.

### Migration

If you already have an instance of CTFNote in a previous version and wish to
upgrade, you should follow the guide at [MIGRATION.md](MIGRATION.md).


## Privileges

When other players register on your CTFNote instance, they will not be able to
see CTF or tasks. This is because CTFNote uses different roles to restrict CTF

You can manage other players' roles in the *Users* tab of the *Admin* panel.
You can manage other players' roles in the _Users_ tab of the _Admin_ panel.

Additionally, you can generate a secret that lets users create an account with a
different privilege in the *Registration with password* menu in the *Admin*
different privilege in the _Registration with password_ menu in the _Admin_
panel.

![Screenshot of the Registration with password menu](screenshots/reg_password.png)

### Guest

Guest is the default role. This role is meant to be used for guests and friends
helping sporadically on CTF.

You can add a guest to a CTF by ticking their badge in the *Guests* tab on a
You can add a guest to a CTF by ticking their badge in the _Guests_ tab on a
specific CTF.

![Screenshot of the guest menu](screenshots/guests.png)

### Friend
Friend is a role between guest and member which allows the player to automatically

Friend is a role between guest and member which allows the player to automatically
view old CTFs but not active and upcoming CTFs. They are also not allowed to invite any
new players to a CTF. You can use this role to grant guests access to your old CTFs
for them to learn from without granting access to each old CTF individually.

### Member

Member is a role that represents a team member. A certain level of trust is
given to these users: they can see every CTF, future, current and past. They can
also invite guests to CTF.

### Manager

Manager is a role that represents a team captain. They can create, import,
modify and delete CTF.

Expand All @@ -118,32 +125,42 @@ They can import CTF directly from [CTFtime](https://ctftime.org).
![Screenshot of the Import CTF feature](screenshots/import.png)

### Admin
Admin is a role with every privileges. They have access to the *Admin* panel

Admin is a role with every privileges. They have access to the _Admin_ panel
that lets them delete accounts, change permissions, reset passwords, create
one-time secrets and, most importantly, change the theme colours.

![Screenshot of the theme menu](screenshots/theme.png)


## Configuration

The configuration can be changed in the `.env` file. This file contains
environment variables for the containers.

The value of every variables are explained in this file.


## Screenshots

### List of the CTF

[![Screenshot of the CTF page](screenshots/ctf_small.webp)](screenshots/ctf.png)

### Calendar

[![Screenshot of the CTF calendar](screenshots/calendar_small.webp)](screenshots/calendar.png)

### Information of a single CTF

[![Screenshot of the CTF info](screenshots/info_small.webp)](screenshots/info.png)

### Task list for a CTF

[![Screenshot of the task list](screenshots/task_small.webp)](screenshots/task.png)

### Shared notepad for a task

[![Screenshot of pad](screenshots/pad_small.webp)](screenshots/pad.png)

## Contributing

A contribution guide is available here: [CONTRIBUTING.md](CONTRIBUTING.md)
2 changes: 2 additions & 0 deletions api/migrations/40-search-tasks-n-ctfs.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
CREATE INDEX ON ctfnote.ctf (title);
CREATE INDEX ON ctfnote.task (title);
6 changes: 3 additions & 3 deletions api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
},
Expand All @@ -27,8 +27,8 @@
"graphile-utils": "^4.11.2",
"graphql": "^15.6.1",
"graphql-upload": "^12.0.0",
"postgraphile": "^4.11.0",
"postgraphile-plugin-connection-filter": "^2.1.1",
"postgraphile": "^4.12.8",
"postgraphile-plugin-connection-filter": "^2.2.2",
"postgres-migrations": "^5.3.0"
},
"devDependencies": {
Expand Down
12 changes: 11 additions & 1 deletion api/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import createTasKPlugin from "./plugins/createTask";
import importCtfPlugin from "./plugins/importCtf";
import uploadLogoPlugin from "./plugins/uploadLogo";
import uploadScalar from "./plugins/uploadScalar";
import ConnectionFilterPlugin from "postgraphile-plugin-connection-filter";

function getDbUrl(role: "user" | "admin") {
const login = config.db[role].login;
Expand Down Expand Up @@ -43,6 +44,7 @@ function createOptions() {
importCtfPlugin,
uploadLogoPlugin,
createTasKPlugin,
ConnectionFilterPlugin,
],
ownerConnectionString: getDbUrl("admin"),
enableQueryBatching: true,
Expand All @@ -60,6 +62,14 @@ function createOptions() {
postgraphileOptions.jwtSecret = "DEV";
postgraphileOptions.showErrorStack = "json" as const;
postgraphileOptions.extendedErrors = ["hint", "detail", "errcode"];

postgraphileOptions.graphileBuildOptions = {
connectionFilterAllowedOperators: ["includesInsensitive"],
connectionFilterAllowedFieldTypes: ["String"],
connectionFilterComputedColumns: false,
connectionFilterSetofFunctions: false,
connectionFilterArrays: false,
};
}
return postgraphileOptions;
}
Expand All @@ -70,7 +80,7 @@ function createApp(postgraphileOptions: PostGraphileOptions) {
app.use(
"/uploads",
express.static("uploads", {
setHeaders: function (res, path, stat) {
setHeaders: function (res) {
res.set("Content-Disposition", "attachment");
},
})
Expand Down
62 changes: 56 additions & 6 deletions api/src/plugins/createTask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,52 @@ import axios from "axios";
import savepointWrapper from "./savepointWrapper";
import config from "../config";

async function createPad(): Promise<string> {
function buildNoteContent(
title: string,
description?: string,
category?: string
): string {
let note = "";

note += `# ${title}`;

if (category) {
note += ` - ${category}`;
}

note += "\n\n";

if (description) {
note += `## Description\n`;
note += "\n";
note += `${description}\n`;

note += "\n";
note += "----\n";
}
return note;
}

async function createPad(
title: string,
description?: string,
category?: string
): Promise<string> {
const options = {
headers: {
"Content-Type": "text/markdown",
},

maxRedirects: 0,
validateStatus: (status: number) => status === 302,
};

try {
const res = await axios.get(config.pad.createUrl, {
maxRedirects: 0,
validateStatus: (status) => status === 302,
});
const res = await axios.post(
config.pad.createUrl,
buildNoteContent(title, description, category),
options
);
return res.headers.location;
} catch (e) {
throw Error(`Call to ${config.pad.createUrl} during task creation failed.`);
Expand Down Expand Up @@ -44,7 +84,17 @@ export default makeExtendSchemaPlugin((build) => {
{ pgClient },
resolveInfo
) => {
const padPathOrUrl = await createPad();
const {
rows: [isAllowed],
} = await pgClient.query(`SELECT ctfnote_private.can_play_ctf($1)`, [
ctfId,
]);

if (isAllowed.can_play_ctf !== true) {
return {};
}

const padPathOrUrl = await createPad(title, description, category);

let padPath: string;
if (padPathOrUrl.startsWith("/")) {
Expand Down
Loading