Skip to content

Commit

Permalink
0.6.5
Browse files Browse the repository at this point in the history
- Fixed a bug where an error message will show when loading challenges via direct link
- Minor CSS fixes to the Tables in admin panel
- Refresh function for admin panels
- Copy challenge link to clipboard in challenge page
  • Loading branch information
Tkaixiang committed May 20, 2021
1 parent eeec218 commit 6c9654d
Show file tree
Hide file tree
Showing 9 changed files with 305 additions and 215 deletions.
4 changes: 4 additions & 0 deletions client/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,8 @@

.ant-table {
background:rgba(0, 0, 0, 0.5) !important;
}

.ant-table-container {
overflow: auto;
}
4 changes: 3 additions & 1 deletion client/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ class App extends React.Component {
previousPage = page
}

message.config({maxCount: 2})

// Handles "remember me" logins
if (!this.state.token) {
const token = localStorage.getItem("IRSCTF-token")
Expand Down Expand Up @@ -263,7 +265,7 @@ class App extends React.Component {

</Menu>
<div style={{ textAlign: "center", marginTop: "3ch", color: "#8c8c8c" }}>
<p>Sieberrsec CTF Platform 0.6.1 <a href="https://github.com/IRS-Cybersec/ctf_platform" target="_blank">Contribute <GithubOutlined /></a></p>
<p>Sieberrsec CTF Platform 0.6.5 <a href="https://github.com/IRS-Cybersec/ctf_platform" target="_blank">Contribute <GithubOutlined /></a></p>
</div>
</Sider>

Expand Down
169 changes: 85 additions & 84 deletions client/src/adminChallenges.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import {
EditOutlined,
FileUnknownTwoTone,
EyeOutlined,
EyeInvisibleOutlined
EyeInvisibleOutlined,
RedoOutlined
} from '@ant-design/icons';
import './App.css';
import AdminChallengeCreate from "./adminChallengeCreate.js";
Expand Down Expand Up @@ -36,19 +37,20 @@ class AdminChallenges extends React.Component {
selectedKeys: [],
targetKeys: [],
allCat: [],
transferDisabled: false
transferDisabled: false,
refreshLoading: false
}
}

componentDidUpdate(prevProps) {
// Handle any page changes
if (this.state.editChallenge && this.props.location.pathname !== "/Admin/Challenges/Edit") {
this.setState({ editChallenge: false })
}
else if (this.state.challengeCreate && this.props.location.pathname !== "/Admin/Challenges/Create") {
this.setState({ challengeCreate: false })
componentDidUpdate(prevProps) {
// Handle any page changes
if (this.state.editChallenge && this.props.location.pathname !== "/Admin/Challenges/Edit") {
this.setState({ editChallenge: false })
}
else if (this.state.challengeCreate && this.props.location.pathname !== "/Admin/Challenges/Create") {
this.setState({ challengeCreate: false })
}
}
}


componentDidMount = async () => {
Expand All @@ -60,38 +62,36 @@ class AdminChallenges extends React.Component {
message.warn("Please select a challenge from the table to edit")
await this.props.history.push("/Admin/Challenges")
}
this.fillTableData()
this.handleCategoryData()
this.handleRefresh()
}


handleCategoryData() {
handleCategoryData = async () => {
this.setState({ transferDisabled: true })
let visibleCat = []
let allCat = []

const getInfo = async () => {
fetch(window.ipAddress + "/v1/challenge/list_categories", {
method: 'get',
headers: { 'Content-Type': 'application/json', "Authorization": localStorage.getItem("IRSCTF-token") },
}).then((results) => {
return results.json(); //return data in JSON (since its JSON data)
}).then((data) => {
await Promise.all([fetch(window.ipAddress + "/v1/challenge/list_categories", {
method: 'get',
headers: { 'Content-Type': 'application/json', "Authorization": localStorage.getItem("IRSCTF-token") },
}).then((results) => {
return results.json(); //return data in JSON (since its JSON data)
}).then((data) => {

if (data.success === true) {
visibleCat = data.categories
}
else {
message.error({ content: "Oops. Unknown error" })
}
if (data.success === true) {
visibleCat = data.categories
}
else {
message.error({ content: "Oops. Unknown error" })
}


}).catch((error) => {
console.log(error)
message.error({ content: "Oops. There was an issue connecting with the server" });
})
}).catch((error) => {
console.log(error)
message.error({ content: "Oops. There was an issue connecting with the server" });
})

await fetch(window.ipAddress + "/v1/challenge/list_all_categories", {
, fetch(window.ipAddress + "/v1/challenge/list_all_categories", {
method: 'get',
headers: { 'Content-Type': 'application/json', "Authorization": localStorage.getItem("IRSCTF-token") },
}).then((results) => {
Expand All @@ -110,22 +110,17 @@ class AdminChallenges extends React.Component {
console.log(error)
message.error({ content: "Oops. There was an issue connecting with the server" });
})
])

let invisible = difference(allCat, visibleCat)
/*console.log(invisible)
console.log(allCat)
console.log(visibleCat)*/

for (let i = 0; i < allCat.length; i++) {
allCat[i] = { "key": allCat[i] }
}

(async () => {
await getInfo()
let invisible = difference(allCat, visibleCat)
/*console.log(invisible)
console.log(allCat)
console.log(visibleCat)*/

for (let i = 0; i < allCat.length; i++) {
allCat[i] = { "key": allCat[i] }
}
this.setState({ targetKeys: invisible, allCat: allCat, transferDisabled: false })
})()
this.setState({ targetKeys: invisible, allCat: allCat, transferDisabled: false })
}

handleChange = (nextTargetKeys, direction, moveKeys) => {
Expand Down Expand Up @@ -172,9 +167,9 @@ class AdminChallenges extends React.Component {
})
}

fillTableData = () => {
fillTableData = async () => {
this.setState({ loading: true })
fetch(window.ipAddress + "/v1/challenge/list_all", {
await fetch(window.ipAddress + "/v1/challenge/list_all", {
method: 'get',
headers: { 'Content-Type': 'application/json', "Authorization": localStorage.getItem("IRSCTF-token") },
}).then((results) => {
Expand All @@ -191,6 +186,7 @@ class AdminChallenges extends React.Component {
}
}
this.setState({ dataSource: data.challenges, loading: false })

}
else {
message.error({ content: "Oops. Unknown error" })
Expand All @@ -217,8 +213,7 @@ class AdminChallenges extends React.Component {
//console.log(data)
if (data.success === true) {
message.success({ content: "Deleted challenge \"" + challengeName + "\" successfully" })
this.fillTableData()
this.handleCategoryData()
this.handleRefresh()

}
else {
Expand Down Expand Up @@ -249,15 +244,17 @@ class AdminChallenges extends React.Component {
handleCreateBack() {
this.props.history.push("/Admin/Challenges")
this.setState({ challengeCreate: false })
this.fillTableData()
this.handleCategoryData()
this.handleRefresh()
}

handleEditChallBack() {
this.props.history.push("/Admin/Challenges")
this.setState({ editChallenge: false })
this.fillTableData()
this.handleCategoryData()
this.handleRefresh()
}

handleRefresh = async () => {
await Promise.all([this.fillTableData(), this.handleCategoryData()])
}


Expand All @@ -269,24 +266,26 @@ class AdminChallenges extends React.Component {

<Layout style={{ height: "100%", width: "100%", backgroundColor: "rgba(0, 0, 0, 0)" }}>

{this.state.loading && (
<div style={{ position: "absolute", left: "55%", transform: "translate(-55%, 0%)", zIndex: 10 }}>
<Ellipsis color="#177ddc" size={120} ></Ellipsis>
</div>
)}
{!this.state.loading && (
<div>

{!this.state.challengeCreate && !this.state.editChallenge && (
<div>

<Button type="primary" style={{ marginBottom: "2vh", maxWidth: "25ch" }} icon={<FlagOutlined />} onClick={() => { this.setState({ challengeCreate: true }, this.props.history.push("/Admin/Challenges/Create")) }}>Create New Challenge</Button>

{!this.state.challengeCreate && !this.state.editChallenge && (
<div>
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
<Button type="primary" style={{ marginBottom: "2vh", maxWidth: "25ch" }} icon={<FlagOutlined />} onClick={() => { this.setState({ challengeCreate: true }, this.props.history.push("/Admin/Challenges/Create")) }}>Create New Challenge</Button>
<Button loading={this.state.loading} type="primary" shape="circle" size="large" style={{ marginBottom: "2vh", maxWidth: "25ch" }} icon={<RedoOutlined />} onClick={async () => { await this.handleRefresh(); message.success("Challenge list refreshed.") }} />
</div>
{this.state.loading && (
<div style={{ display: "flex", justifyContent: "center", alignItems: "center" }}>
<Ellipsis color="#177ddc" size={120} ></Ellipsis>
</div>
)}
{!this.state.loading && (
<div>
<Table style={{ overflow: "auto" }} dataSource={this.state.dataSource} locale={{
emptyText: (
<div style={{ display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", marginTop: "10vh" }}>
<FileUnknownTwoTone style={{ color: "#177ddc", fontSize: "400%", zIndex: 1 }} />
<h1 style={{ fontSize: "200%" }}>There are no challenges created.</h1>
<h1 style={{ fontSize: "200%" }}>No Challenges Have Been Created.</h1>
</div>
)
}}>
Expand Down Expand Up @@ -329,35 +328,37 @@ class AdminChallenges extends React.Component {
)}
/>
</Table>
<Divider />
<h1 style={{ fontSize: "150%" }}>Category Management {this.state.transferDisabled && (<LoadingOutlined style={{ color: "#177ddc" }} />)}</h1>

<Transfer
dataSource={this.state.allCat}
titles={['Visible Categories', 'Hidden Categories']}
targetKeys={this.state.targetKeys}
selectedKeys={this.state.selectedKeys}
onChange={this.handleChange}
onSelectChange={this.handleSelectChange}
render={item => item.key}
pagination
disabled={this.state.transferDisabled}
/>

<Divider />
</div>
)}
<Switch>
<Route exact path='/Admin/Challenges/Create' render={(props) => <AdminChallengeCreate {...props} handleBack={this.handleBack.bind(this)} handleCreateBack={this.handleCreateBack.bind(this)} allCat={this.state.allCat} />} />
<Route exact path='/Admin/Challenges/Edit' render={(props) => <AdminChallengeEdit {...props} allCat={this.state.allCat} challengeName={this.state.challengeName} handleEditBack={this.handleEditBack.bind(this)} handleEditChallBack={this.handleEditChallBack.bind(this)} />} />
<Divider />
<h1 style={{ fontSize: "150%" }}>Category Management {this.state.transferDisabled && (<LoadingOutlined style={{ color: "#177ddc" }} />)}</h1>

<Transfer
dataSource={this.state.allCat}
titles={['Visible Categories', 'Hidden Categories']}
targetKeys={this.state.targetKeys}
selectedKeys={this.state.selectedKeys}
onChange={this.handleChange}
onSelectChange={this.handleSelectChange}
render={item => item.key}
pagination
disabled={this.state.transferDisabled}
/>

</Switch>
<Divider />



</div>
)}


<Switch>
<Route exact path='/Admin/Challenges/Create' render={(props) => <AdminChallengeCreate {...props} handleBack={this.handleBack.bind(this)} handleCreateBack={this.handleCreateBack.bind(this)} allCat={this.state.allCat} />} />
<Route exact path='/Admin/Challenges/Edit' render={(props) => <AdminChallengeEdit {...props} allCat={this.state.allCat} challengeName={this.state.challengeName} handleEditBack={this.handleEditBack.bind(this)} handleEditChallBack={this.handleEditChallBack.bind(this)} />} />

</Switch>

</Layout>
);
}
Expand Down
13 changes: 9 additions & 4 deletions client/src/adminSubmissions.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React from 'react';
import { Layout, Table, message } from 'antd';
import { Layout, Table, message, Button } from 'antd';
import {
FileUnknownTwoTone,
RedoOutlined
} from '@ant-design/icons';
import { orderBy } from "lodash";
import { Ellipsis } from 'react-spinners-css';
Expand All @@ -25,9 +26,9 @@ class AdminSubmissions extends React.Component {
this.fillTableData()
}

fillTableData = () => {
fillTableData = async () => {
this.setState({ loading: true })
fetch(window.ipAddress + "/v1/submissions", {
await fetch(window.ipAddress + "/v1/submissions", {
method: 'get',
headers: { 'Content-Type': 'application/json', "Authorization": localStorage.getItem("IRSCTF-token") },
}).then((results) => {
Expand Down Expand Up @@ -69,6 +70,10 @@ class AdminSubmissions extends React.Component {

<Layout style={{ height: "100%", width: "100%", backgroundColor: "rgba(0, 0, 0, 0)" }}>

<div style={{ display: "flex", justifyContent: "flex-end", alignItems: "center" }}>
<Button loading={this.state.loading} type="primary" shape="circle" size="large" style={{ marginBottom: "2vh", maxWidth: "25ch" }} icon={<RedoOutlined />} onClick={async () => { await this.fillTableData(); message.success("Submissions list refreshed.") }} />
</div>

{this.state.loading && (
<div style={{ position: "absolute", left: "55%", transform: "translate(-55%, 0%)", zIndex: 10 }}>
<Ellipsis color="#177ddc" size={120} ></Ellipsis>
Expand All @@ -95,7 +100,7 @@ class AdminSubmissions extends React.Component {
<Column title="Correct" dataIndex="correct" key="correct" />
</Table>
)}
</Layout>
</Layout >
);
}
}
Expand Down
Loading

0 comments on commit 6c9654d

Please sign in to comment.