Skip to content

Commit a14c52c

Browse files
feat: edit corpsync web challenge
1 parent e20ebe9 commit a14c52c

5 files changed

Lines changed: 50 additions & 4 deletions

File tree

challenges/web/CorpSync/challenge/app1/app.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const {
1313
addUser,
1414
createReport,
1515
getReports,
16+
getReportsByUser,
1617
getReportById,
1718
updateReportStatus,
1819
getSessionSecret,
@@ -101,11 +102,19 @@ app.post("/logout", requireAuth, (req, res) => {
101102
});
102103

103104
app.get("/dashboard", requireAuth, async (req, res) => {
104-
res.render("dashboard", { reports: await getReports() });
105+
const { userId, role } = req.session.data;
106+
const reports = ["reporter", "admin"].includes(role)
107+
? await getReports()
108+
: await getReportsByUser(userId);
109+
res.render("dashboard", { reports });
105110
});
106111

107112
app.get("/reports", requireAuth, async (req, res) => {
108-
res.render("reports", { reports: await getReports() });
113+
const { userId, role } = req.session.data;
114+
const reports = ["reporter", "admin"].includes(role)
115+
? await getReports()
116+
: await getReportsByUser(userId);
117+
res.render("reports", { reports });
109118
});
110119

111120
app.get("/reports/new", requireAuth, (req, res) => res.render("report_new", { error: null }));
@@ -122,12 +131,20 @@ app.post("/reports/new", requireAuth, async (req, res) => {
122131
app.get("/reports/:id", requireAuth, async (req, res) => {
123132
const report = await getReportById(req.params.id);
124133
if (!report) return res.status(404).send("Report not found");
134+
const { userId, role } = req.session.data;
135+
if (!["reporter", "admin"].includes(role) && report.created_by !== userId) {
136+
return res.status(403).render("forbidden", { user: req.session.data, sessionToken: res.locals.sessionToken });
137+
}
125138
res.render("report_view", { report, message: null });
126139
});
127140

128141
app.post("/reports/:id/flag", requireAuth, async (req, res) => {
129142
const report = await getReportById(req.params.id);
130143
if (!report) return res.status(404).send("Report not found");
144+
const { userId, role } = req.session.data;
145+
if (!["reporter", "admin"].includes(role) && report.created_by !== userId) {
146+
return res.status(403).render("forbidden", { user: req.session.data, sessionToken: res.locals.sessionToken });
147+
}
131148
await updateReportStatus(report.id, "In Review");
132149
fetch(BOT_URL, {
133150
method: "POST",

challenges/web/CorpSync/challenge/app1/db.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,12 @@ const getReports = () =>
101101
FROM reports r JOIN users u ON r.created_by = u.id
102102
ORDER BY r.created_at DESC`);
103103

104+
const getReportsByUser = (userId) =>
105+
all(`SELECT r.*, u.username AS author
106+
FROM reports r JOIN users u ON r.created_by = u.id
107+
WHERE r.created_by = ?
108+
ORDER BY r.created_at DESC`, [userId]);
109+
104110
const getReportById = (id) =>
105111
get(`SELECT r.*, u.username AS author
106112
FROM reports r JOIN users u ON r.created_by = u.id
@@ -116,6 +122,7 @@ module.exports = {
116122
addUser,
117123
createReport,
118124
getReports,
125+
getReportsByUser,
119126
getReportById,
120127
updateReportStatus,
121128
};
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<%- include('partials/header', { user, sessionToken }) %>
2+
<div style="display:flex;flex-direction:column;align-items:center;justify-content:center;min-height:60vh;text-align:center;gap:0">
3+
<div style="width:72px;height:72px;border-radius:50%;background:var(--red-bg);border:1px solid var(--red-bd);display:grid;place-items:center;margin-bottom:24px">
4+
<svg viewBox="0 0 16 16" fill="currentColor" style="width:32px;height:32px;color:var(--red)">
5+
<path d="M8 1a2 2 0 012 2v4H6V3a2 2 0 012-2m3 6V3a3 3 0 00-6 0v4a2 2 0 00-2 2v5a2 2 0 002 2h6a2 2 0 002-2V9a2 2 0 00-2-2"/>
6+
</svg>
7+
</div>
8+
<div style="font-size:64px;font-weight:800;color:var(--text);letter-spacing:-3px;line-height:1">403</div>
9+
<div style="font-size:18px;font-weight:700;color:var(--text);margin-top:10px;margin-bottom:8px">Access Denied</div>
10+
<div style="font-size:13px;color:var(--muted);max-width:340px;line-height:1.65;margin-bottom:28px">
11+
You don't have permission to view this report.<br>Only the report's author can access it.
12+
</div>
13+
<div style="display:flex;gap:10px">
14+
<a href="/dashboard" class="btn btn-primary">
15+
<svg viewBox="0 0 16 16" fill="currentColor"><path d="M1 2.5A1.5 1.5 0 012.5 1h3A1.5 1.5 0 017 2.5v3A1.5 1.5 0 015.5 7h-3A1.5 1.5 0 011 5.5zm7.5 0A1.5 1.5 0 0110 1h3a1.5 1.5 0 011.5 1.5v3A1.5 1.5 0 0113 7h-3a1.5 1.5 0 01-1.5-1.5zm-7.5 7A1.5 1.5 0 012.5 8h3A1.5 1.5 0 017 9.5v3A1.5 1.5 0 015.5 14h-3A1.5 1.5 0 011 12.5zm7.5 0A1.5 1.5 0 0110 8h3a1.5 1.5 0 011.5 1.5v3a1.5 1.5 0 01-1.5 1.5h-3a1.5 1.5 0 01-1.5-1.5z"/></svg>
16+
Dashboard
17+
</a>
18+
<a href="/reports" class="btn btn-outline">My Reports</a>
19+
</div>
20+
</div>
21+
<%- include('partials/footer') %>

challenges/web/CorpSync/challenge/app1/views/reports.ejs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,11 @@
3434
<td><span class="badge <%= bc(r.status) %>"><%= r.status %></span></td>
3535
<td style="color:var(--subtle);font-size:12px"><%= new Date(r.created_at).toLocaleDateString('en-GB', {day:'2-digit',month:'short',year:'numeric'}) %></td>
3636
<td>
37+
<% if (['reporter','admin'].includes(user.role) || r.created_by === user.userId) { %>
3738
<form method="POST" action="/reports/<%= r.id %>/flag">
3839
<button type="submit" class="btn btn-outline btn-sm">Flag</button>
3940
</form>
41+
<% } %>
4042
</td>
4143
</tr>
4244
<% }) %>

challenges/web/CorpSync/challenge/bot/bot.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,7 @@ async function visit(browser, url) {
3535
}
3636

3737
async function main() {
38-
// Chrome has its own DNS resolver that doesn't use Docker's embedded DNS.
39-
// Pre-resolve the app1 hostname with Node and pass it to Chrome via --host-resolver-rules.
38+
4039
const appHostname = new URL(APP1_URL).hostname;
4140
let resolverRule = "";
4241
try {

0 commit comments

Comments
 (0)