mirror of
https://github.com/aljazceru/CTFd.git
synced 2025-12-18 06:24:23 +01:00
Render hints on server side and don't render them client side (#1564)
* Render hints on the server side inline with challenge descriptions and Pages * Clean up some of the API responses for hints to include the right data * Closes #1563
This commit is contained in:
@@ -68,7 +68,7 @@ class HintList(Resource):
|
|||||||
filters = build_model_filters(model=Hints, query=q, field=field)
|
filters = build_model_filters(model=Hints, query=q, field=field)
|
||||||
|
|
||||||
hints = Hints.query.filter_by(**query_args).filter(*filters).all()
|
hints = Hints.query.filter_by(**query_args).filter(*filters).all()
|
||||||
response = HintSchema(many=True).dump(hints)
|
response = HintSchema(many=True, view="locked").dump(hints)
|
||||||
|
|
||||||
if response.errors:
|
if response.errors:
|
||||||
return {"success": False, "errors": response.errors}, 400
|
return {"success": False, "errors": response.errors}, 400
|
||||||
@@ -88,7 +88,7 @@ class HintList(Resource):
|
|||||||
)
|
)
|
||||||
def post(self):
|
def post(self):
|
||||||
req = request.get_json()
|
req = request.get_json()
|
||||||
schema = HintSchema("admin")
|
schema = HintSchema(view="admin")
|
||||||
response = schema.load(req, session=db.session)
|
response = schema.load(req, session=db.session)
|
||||||
|
|
||||||
if response.errors:
|
if response.errors:
|
||||||
@@ -155,7 +155,7 @@ class Hint(Resource):
|
|||||||
hint = Hints.query.filter_by(id=hint_id).first_or_404()
|
hint = Hints.query.filter_by(id=hint_id).first_or_404()
|
||||||
req = request.get_json()
|
req = request.get_json()
|
||||||
|
|
||||||
schema = HintSchema()
|
schema = HintSchema(view="admin")
|
||||||
response = schema.load(req, instance=hint, partial=True, session=db.session)
|
response = schema.load(req, instance=hint, partial=True, session=db.session)
|
||||||
|
|
||||||
if response.errors:
|
if response.errors:
|
||||||
|
|||||||
@@ -134,6 +134,13 @@ class Hints(db.Model):
|
|||||||
def description(self):
|
def description(self):
|
||||||
return "Hint for {name}".format(name=self.challenge.name)
|
return "Hint for {name}".format(name=self.challenge.name)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def html(self):
|
||||||
|
from CTFd.utils.config.pages import build_html
|
||||||
|
from CTFd.utils.helpers import markup
|
||||||
|
|
||||||
|
return markup(build_html(self.content))
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(Hints, self).__init__(**kwargs)
|
super(Hints, self).__init__(**kwargs)
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,4 @@
|
|||||||
CTFd.plugin.run((_CTFd) => {
|
CTFd.plugin.run((_CTFd) => {
|
||||||
const $ = _CTFd.lib.$
|
const $ = _CTFd.lib.$
|
||||||
const md = _CTFd.lib.markdown()
|
const md = _CTFd.lib.markdown()
|
||||||
$('a[href="#new-desc-preview"]').on('shown.bs.tab', function (event) {
|
|
||||||
if (event.target.hash == '#new-desc-preview') {
|
|
||||||
var editor_value = $('#new-desc-editor').val();
|
|
||||||
$(event.target.hash).html(
|
|
||||||
md.render(editor_value)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -6,12 +6,12 @@ class HintSchema(ma.ModelSchema):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = Hints
|
model = Hints
|
||||||
include_fk = True
|
include_fk = True
|
||||||
dump_only = ("id", "type")
|
dump_only = ("id", "type", "html")
|
||||||
|
|
||||||
views = {
|
views = {
|
||||||
"locked": ["id", "type", "challenge", "cost"],
|
"locked": ["id", "type", "challenge", "cost"],
|
||||||
"unlocked": ["id", "type", "challenge", "content", "cost"],
|
"unlocked": ["id", "type", "challenge", "content", "html", "cost"],
|
||||||
"admin": ["id", "type", "challenge", "content", "cost", "requirements"],
|
"admin": ["id", "type", "challenge", "content", "html", "cost", "requirements"],
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, view=None, *args, **kwargs):
|
def __init__(self, view=None, *args, **kwargs):
|
||||||
|
|||||||
@@ -23,12 +23,10 @@ import {
|
|||||||
flagTypeSelect
|
flagTypeSelect
|
||||||
} from "../challenges/flags";
|
} from "../challenges/flags";
|
||||||
|
|
||||||
const md = CTFd.lib.markdown();
|
|
||||||
|
|
||||||
const displayHint = data => {
|
const displayHint = data => {
|
||||||
ezAlert({
|
ezAlert({
|
||||||
title: "Hint",
|
title: "Hint",
|
||||||
body: md.render(data.content),
|
body: data.html,
|
||||||
button: "Got it!"
|
button: "Got it!"
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -12,8 +12,6 @@ const api_func = {
|
|||||||
users: x => CTFd.api.get_user_solves({ userId: x })
|
users: x => CTFd.api.get_user_solves({ userId: x })
|
||||||
};
|
};
|
||||||
|
|
||||||
const md = CTFd.lib.markdown();
|
|
||||||
|
|
||||||
CTFd._internal.challenge = {};
|
CTFd._internal.challenge = {};
|
||||||
let challenges = [];
|
let challenges = [];
|
||||||
let solves = [];
|
let solves = [];
|
||||||
@@ -393,7 +391,7 @@ setInterval(update, 300000); // Update every 5 minutes.
|
|||||||
const displayHint = data => {
|
const displayHint = data => {
|
||||||
ezAlert({
|
ezAlert({
|
||||||
title: "Hint",
|
title: "Hint",
|
||||||
body: md.render(data.content),
|
body: data.html,
|
||||||
button: "Got it!"
|
button: "Got it!"
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -418,7 +416,7 @@ const displayUnlock = id => {
|
|||||||
|
|
||||||
ezAlert({
|
ezAlert({
|
||||||
title: "Error",
|
title: "Error",
|
||||||
body: md.render(response.errors.score),
|
body: response.errors.score,
|
||||||
button: "Got it!"
|
button: "Got it!"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user