const accountSchema = new Schema({
id: { type: String, unique: true, required: true},
password: { type: String, required: true},
salt: { type: String, required: true},
email: { type: String, unique: true, required: true},
verified: { type: Boolean, required: true, default: false },
authority: { type: Number, required: true, default: 0 },
test: { type: Boolean, required: true, default: false },
});
module.exports = accountSchema;
const contestSchema = new Schema({
name: { type: String, unique: true, required: true },
description: { type: String },
problems: { type: [String], required: true}, // problem name
begin_at: { type: String, required: true },
end_at: { type: String, required: true },
participants: { type: [String], required: true }, // account id
state: { type: String, required: true, default: '0' }, // 0 : upcoming, 1 : in progress, 2 : ended, 3 : suspended
test: { type: Boolean, required: true, default: false },
});
const problemSchema = new Schema({
name: { type: String, unique: true, required: true },
description: { type: String },
file: { type: String },
flag: { type: String },
url: {type: String},
port: {type: String},
score: { type: String, required: true },
domain: { type: String, required: true }, // pwn, web, forensic, reverse, misc
contest: { type: String }, // contest name
test: { type: Boolean, required: true, default: false },
});
const profileSchema = new Schema({
id: { type: String, unique: true, required: true },
email: { type: String, unique: true, required: true},
name: { type: String, required: true },
organization: { type: String, required: true },
department: { type: String, required: true },
solved: { type: [Schema.ObjectId], default: [] },
test: { type: Boolean, required: true, default: false },
});
/*
solved : [
// problem names
]
*/
const scoreboardSchema = new Schema({
contest: { type: String, unique: true, required: true }, // contest name
begin_at: { type: String, required: true },
end_at: { type: String, required: true },
sumbissions: { type: [Object], default: [] },
test: { type: Boolean, required: true, default: false }
});
/*
submission : [
{
problem : problem name,
score : problem score,
account : account id,
time : time (YYYY-MM-DD HH:MM:SS)
}
]
*/
-
계정 생성 후 프로필 생성을 한다.
-
세션이 있으면 실패한다.
-
ID/Email 중복 확인을 한다.
-
Request Body
{
"id": "exampleId",
"password": "examplePassword",
"email": "exampleEmail",
"name": "exampleName",
"organization": "exampleOrganization",
"department": "exampleDepartment"
}
- Response
{
"code": 0,
"data": {}
}
-
계정 로그인을 한다.
-
세션을 생성하고 쿠키에 저장한다.
-
세션에는 ID와 Token이 저장된다.
-
Request Body
{
"id": "exampleId",
"password": "examplePassword"
}
- Response
{
"code": 0,
"data": {}
}
-
유효한 세션인지 확인한다.
-
Response
{
"code": 0,
"data": {}
}
-
계정 로그아웃을 한다.
-
세션을 제거하고 쿠키를 제거한다.
-
Response
{
"code": 0,
"data": {}
}
-
계정 토큰을 갱신한다.
-
Response
{
"code": 0,
"data": {}
}
-
유효한 세션인지 확인한다.
-
계정 비밀번호를 변경한다.
-
Request Body
{
"id": "exampleId",
"password": "examplePassword",
"newPassword": "exampleNewPassword"
}
- Response
{
"code": 0,
"data": {}
}
-
유효한 세션인지 확인한다.
-
계정과 프로필을 삭제한다.
-
Request Body
{
"id": "exampleId",
"password": "examplePassword"
}
- Response
{
"code": 0,
"data": {}
}
-
최근에 진행된
contest
를count
만큼 가져온다. -
Parameters
{
"count": 5
}
- Response
{
"code": 0,
"data": {
"recent" : [...],
"upcoming" : [...],
"inprogress" : [...],
"ended" : [...]
}
}
-
contest
의 정보를 가져온다. -
name
이 있으면 해당 이름을 가진contest
를 가져온다. -
name
이 있고 세션이 유효하며contest
의participants
에 속하면problems
나scoreboards
를 가져올 수 있다. -
Parameters
{
"name": "exampleContest",
"problems": true,
"scoreboards": true
}
- Response
// no params
{
"code": 0,
"data": [
// contests
]
}
// only name
{
"code": 0,
"data": {
// contest info
}
}
// problems or scoreboards
{
"code": 0,
"data": {
// contest info
"problems": [
// problems
],
"scoreboard": {
// scoreboard
}
}
}
-
contest
의scoreboard
를 가져온다. -
세션이 유효하며
contest
의participants
에 속하면 가져올 수 있다. -
Parameters
{
"name": "exampleContest"
}
- Response
{
"code": 0,
"data": {
"contest": "exampleContest",
"begin_at": "YYYY-MM-DD HH:MM:SS",
"end_at": "YYYY-MM-DD HH:MM:SS",
"submissions": [
{
"accountId" : {
"total": 0,
"timestamp": [
{
"problem": "exampleProblem",
"score": 0,
"type": true,
"time": "YYYY-MM-DD HH:MM:SS"
},
...
]
},
...
}
]
}
}
-
문제 목록을 가져온다.
-
Parameters
{
"name": "exampleName",
"category": "exampleCategory",
"contest": "exampleContest"
}
- Response
{
"code": 0,
"data": [
// problems
]
}
-
세션이 유효한지 확인한다
-
flag
를 확인한다. -
profile
의solved
에 추가한다. -
contest
의 시간이begin_at
과end_at
사이인지 확인한다. -
contest
의participants
에 속하는지 확인한다. -
contest
의scoreboard
에 추가한다. -
Request Body
{
"name": "exampleProblem",
"flag": "exampleFlag"
}
- Response (Correct)
// solved
{
"code": 0,
"data": {
"result": true
}
}
// not solved
{
"code": 0,
"data": {
"result": false
}
}
Get the profile
information of the account
.
- Request body
Field | Type | Description |
---|---|---|
id |
string |
Account id. |
- Response
{
"code": 0,
"data": {
"id": "exampleId",
"email": "exampleEmail",
"name": "exampleName",
"organization": "exampleOrganization",
"department": "exampleDepartment"
}
}
-
프로필 정보를 가져온다.
-
Parameters
{
"id": "exampleId",
"name": "exampleName",
"organization": "exampleOrganization",
"department": "exampleDepartment"
}
- Response
{
"code": 0,
"data": [
// profiles
]
}
-
유효한 세션인지 확인한다.
-
프로필을 수정한다.
-
Request body
{
"name": "exampleName",
"organization": "exampleOrganization",
"department": "exampleDepartment"
}
- Response
{
"code": 0,
"data": {}
}
-
프로필의
solved
를 가져온다. -
Parameters
{
"id": "exampleId"
}
- Response
{
"code": 0,
"data": [
// solved
]
}
0
: Success
1000
: MongoDB Insert Error1010
: MongoDB Find Error1020
: MongoDB Update Error1030
: MongoDB Delete Error
2000
: Failed to create account2010
: Failed to find account2020
: Failed to find account by id2030
: Failed to find account by password2031
: Account not found2032
: Password incorrect
2040
: Failed to delete account2050
: Failed to change password2051
: Account not found2052
: Password incorrect
2100
: Failed to create contest2110
: Failed to find contest2120
: Failed to delete contest2130
: Failed to update contest2140
: Failed to update problems in contest2150
: Failed to update participants in contest
2200
: Failed to create problem2210
: Failed to find problem2220
: Failed to delete problem2230
: Failed to update problem
2300
: Failed to create profile2310
: Failed to find profile2320
: Failed to delete profile2330
: Failed to update profile2340
: Failed to update solved in profile
2400
: Failed to create scoreboard2410
: Failed to find scoreboard2420
: Failed to delete scoreboard2430
: Failed to update scoreboard2440
: Failed to update submissions in scoreboard2450
: Failed to find processed scoreboard2451
: Scoreboard not found
2460
: Failed to process submissions in scoreboard
2500
: Session check failed2501
: Session not found2502
: Session data not found
-
POST
/api/account
100
: Account registration failed101
: Session already exists102
: Invalid parameters103
: ID already exists104
: Email already exists
-
POST
/api/account/login
110
: Account login failed111
: Invalid parameters112
: Session save failed
-
GET
/api/account/auth
120
: Session check failed
-
GET
/api/account/logout
130
: Account logout failed131
: Session destroy failed
-
GET
/api/account/refresh
140
: Account refresh failed141
: Session refresh failed
-
DELETE
/api/account
150
: Account deletion failed151
: Invalid parameters152
: Not allowed153
: Session destroy failed
-
PUT
/api/account
160
: Account password change failed161
: Invalid parameters162
: Password incorrect163
: Session destroy failed
-
GET
/api/contest/recent
200
: Contest find failed
-
GET
/api/contest
210
: Contest find failed211
: Contest not found212
: Not in contest participants
-
GET
/api/contest/scoreboard
220
: Contest find failed221
: Invalid parameters222
: Contest not found223
: Not in contest participants
-
GET
/api/problem
300
: Problem find failed
-
POST
/api/problem/submit
310
: Problem flag check failed311
: Invalid parameters312
: Problem not found313
: Contest not found
-
GET
/api/profile
400
: Profile find failed
-
PUT
/api/profile
410
: Profile update failed411
: Invalid parameters
-
GET
/api/profile/solved
420
: Profile solved find failed421
: Invalid parameters422
: Profile not found