mirror of
https://github.com/9001/copyparty.git
synced 2025-08-17 09:02:15 -06:00
show README.md in directory listings
This commit is contained in:
parent
ca16c4108d
commit
a009ff53f7
23
README.md
23
README.md
|
@ -477,6 +477,10 @@ and there are *two* editors
|
|||
|
||||
* click the bottom-left `π` to open a javascript prompt for debugging
|
||||
|
||||
* files named `.prologue.html` / `.epilogue.html` will be rendered before/after directory listings unless `--no-logues`
|
||||
|
||||
* files named `README.md` / `readme.md` will be rendered after directory listings unless `--no-readme` (but `.epilogue.html` takes precedence)
|
||||
|
||||
|
||||
## searching
|
||||
|
||||
|
@ -757,6 +761,24 @@ below are some tweaks roughly ordered by usefulness:
|
|||
...however it adds an overhead to internal communication so it might be a net loss, see if it works 4 u
|
||||
|
||||
|
||||
# security
|
||||
|
||||
some notes on hardening
|
||||
|
||||
on public copyparty instances with anonymous upload enabled:
|
||||
|
||||
* users can upload html/css/js which will evaluate for other visitors in a few ways,
|
||||
* unless `--no-readme` is set: by uploading/modifying a file named `readme.md`
|
||||
* if `move` access is granted AND none of `--no-logues`, `--no-dot-mv`, `--no-dot-ren` is set: by uploading some .html file and renaming it to `.epilogue.html` (uploading it directly is blocked)
|
||||
|
||||
|
||||
## gotchas
|
||||
|
||||
behavior that might be unexpected
|
||||
|
||||
* users without read-access to a folder can still see the `.prologue.html` / `.epilogue.html` / `README.md` contents, for the purpose of showing a description on how to use the uploader for example
|
||||
|
||||
|
||||
# dependencies
|
||||
|
||||
mandatory deps:
|
||||
|
@ -887,7 +909,6 @@ in the `scripts` folder:
|
|||
roughly sorted by priority
|
||||
|
||||
* hls framework for Someone Else to drop code into :^)
|
||||
* readme.md as epilogue
|
||||
|
||||
|
||||
## discarded ideas
|
||||
|
|
|
@ -363,6 +363,7 @@ def run_argparse(argv, formatter):
|
|||
ap2.add_argument("--no-dot-mv", action="store_true", help="disallow moving dotfiles; makes it impossible to move folders containing dotfiles")
|
||||
ap2.add_argument("--no-dot-ren", action="store_true", help="disallow renaming dotfiles; makes it impossible to make something a dotfile")
|
||||
ap2.add_argument("--no-logues", action="store_true", help="disable rendering .prologue/.epilogue.html into directory listings")
|
||||
ap2.add_argument("--no-readme", action="store_true", help="disable rendering readme.md into directory listings")
|
||||
|
||||
ap2 = ap.add_argument_group('logging options')
|
||||
ap2.add_argument("-q", action="store_true", help="quiet")
|
||||
|
|
|
@ -1875,6 +1875,15 @@ class HttpCli(object):
|
|||
with open(fsenc(fn), "rb") as f:
|
||||
logues[n] = f.read().decode("utf-8")
|
||||
|
||||
readme = ""
|
||||
if not self.args.no_readme and not logues[1]:
|
||||
for fn in ["README.md", "readme.md"]:
|
||||
fn = os.path.join(abspath, fn)
|
||||
if bos.path.exists(fn):
|
||||
with open(fsenc(fn), "rb") as f:
|
||||
readme = f.read().decode("utf-8")
|
||||
break
|
||||
|
||||
ls_ret = {
|
||||
"dirs": [],
|
||||
"files": [],
|
||||
|
@ -1883,6 +1892,7 @@ class HttpCli(object):
|
|||
"acct": self.uname,
|
||||
"perms": perms,
|
||||
"logues": logues,
|
||||
"readme": readme,
|
||||
}
|
||||
j2a = {
|
||||
"vdir": quotep(self.vpath),
|
||||
|
@ -1901,6 +1911,7 @@ class HttpCli(object):
|
|||
"have_b_u": (self.can_write and self.uparam.get("b") == "u"),
|
||||
"url_suf": url_suf,
|
||||
"logues": logues,
|
||||
"readme": readme,
|
||||
"title": html_escape(self.vpath, crlf=True),
|
||||
"srv_info": srv_info,
|
||||
}
|
||||
|
|
|
@ -133,7 +133,8 @@
|
|||
have_mv = {{ have_mv|tojson }},
|
||||
have_del = {{ have_del|tojson }},
|
||||
have_unpost = {{ have_unpost|tojson }},
|
||||
have_zip = {{ have_zip|tojson }};
|
||||
have_zip = {{ have_zip|tojson }},
|
||||
readme = {{ readme|tojson }};
|
||||
</script>
|
||||
<script src="/.cpr/util.js?_={{ ts }}"></script>
|
||||
<script src="/.cpr/browser.js?_={{ ts }}"></script>
|
||||
|
|
|
@ -140,9 +140,10 @@ ebi('op_cfg').innerHTML = (
|
|||
' <div>\n' +
|
||||
' <a id="tooltips" class="tgl btn" href="#" tt="◔ ◡ ◔">ℹ️ tooltips</a>\n' +
|
||||
' <a id="lightmode" class="tgl btn" href="#">☀️ lightmode</a>\n' +
|
||||
' <a id="dotfiles" class="tgl btn" href="#" tt="show hidden files (if server permits)">dotfiles</a>\n' +
|
||||
' <a id="griden" class="tgl btn" href="#" tt="toggle icons or list-view$NHotkey: G">田 the grid</a>\n' +
|
||||
' <a id="thumbs" class="tgl btn" href="#" tt="in icon view, toggle icons or thumbnails$NHotkey: T">🖼️ thumbs</a>\n' +
|
||||
' <a id="dotfiles" class="tgl btn" href="#" tt="show hidden files (if server permits)">dotfiles</a>\n' +
|
||||
' <a id="ireadme" class="tgl btn" href="#" tt="show README.md in folder listings">📜 readme</a>\n' +
|
||||
' </div>\n' +
|
||||
'</div>\n' +
|
||||
(have_zip ? (
|
||||
|
@ -2999,7 +3000,8 @@ var treectl = (function () {
|
|||
var treectl = {
|
||||
"hidden": true,
|
||||
"ls_cb": null,
|
||||
"dir_cb": tree_scrollto
|
||||
"dir_cb": tree_scrollto,
|
||||
"ireadme": bcfg_get('ireadme', true)
|
||||
},
|
||||
entreed = false,
|
||||
fixedpos = false,
|
||||
|
@ -3320,6 +3322,12 @@ var treectl = (function () {
|
|||
ebi('pro').innerHTML = res.logues ? res.logues[0] || "" : "";
|
||||
ebi('epi').innerHTML = res.logues ? res.logues[1] || "" : "";
|
||||
|
||||
clmod(ebi('epi'), 'mdo');
|
||||
if (res.readme)
|
||||
setTimeout(function () {
|
||||
show_readme(res.readme);
|
||||
}, 10);
|
||||
|
||||
document.title = '⇆🎉 ' + uricom_dec(document.location.pathname.slice(1, -1))[0];
|
||||
|
||||
filecols.set_style();
|
||||
|
@ -3372,6 +3380,12 @@ var treectl = (function () {
|
|||
treectl.goto(get_evpath());
|
||||
}
|
||||
|
||||
function treadme(e) {
|
||||
ev(e);
|
||||
treectl.ireadme = !treectl.ireadme;
|
||||
bcfg_set('ireadme', treectl.ireadme);
|
||||
}
|
||||
|
||||
function dyntree(e) {
|
||||
ev(e);
|
||||
dyn = !dyn;
|
||||
|
@ -3393,6 +3407,7 @@ var treectl = (function () {
|
|||
ebi('detree').onclick = treectl.detree;
|
||||
ebi('visdir').onclick = tree_scrollto;
|
||||
ebi('dotfiles').onclick = tdots;
|
||||
ebi('ireadme').onclick = treadme;
|
||||
ebi('dyntree').onclick = dyntree;
|
||||
ebi('twig').onclick = scaletree;
|
||||
ebi('twobytwo').onclick = scaletree;
|
||||
|
@ -3823,6 +3838,7 @@ var light;
|
|||
|
||||
function freshen() {
|
||||
clmod(document.documentElement, "light", light);
|
||||
clmod(document.documentElement, "dark", !light);
|
||||
pbar.drawbuf();
|
||||
pbar.drawpos();
|
||||
vbar.draw();
|
||||
|
@ -4036,6 +4052,51 @@ var msel = (function () {
|
|||
})();
|
||||
|
||||
|
||||
function show_readme(md, url, depth) {
|
||||
if (!treectl.ireadme)
|
||||
return;
|
||||
|
||||
var div = ebi('epi'),
|
||||
errmsg = 'cannot show README.md:\n\n',
|
||||
now = window.location.href.replace(/\/?[?#].*/, "");
|
||||
|
||||
url = url || now;
|
||||
if (url != now)
|
||||
return;
|
||||
|
||||
if (!window['marked']) {
|
||||
if (depth)
|
||||
return toast.warn(10, errmsg + 'failed to load marked.js')
|
||||
|
||||
return import_js('/.cpr/deps/marked.js', function () {
|
||||
show_readme(md, url, 1);
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
clmod(div, 'mdo', 1);
|
||||
div.innerHTML = marked(md, {
|
||||
headerPrefix: 'md-',
|
||||
breaks: true,
|
||||
gfm: true
|
||||
});
|
||||
var links = QSA('#epi a');
|
||||
for (var a = 0, aa = links.length; a < aa; a++) {
|
||||
var href = links[a].getAttribute('href');
|
||||
if (!href.startsWith('#'))
|
||||
continue;
|
||||
|
||||
links[a].setAttribute('href', '#md-' + href.slice(1));
|
||||
}
|
||||
}
|
||||
catch (ex) {
|
||||
toast.warn(10, errmsg + ex);
|
||||
}
|
||||
}
|
||||
if (readme)
|
||||
show_readme(readme);
|
||||
|
||||
|
||||
(function () {
|
||||
try {
|
||||
var tr = ebi('files').tBodies[0].rows;
|
||||
|
|
|
@ -365,6 +365,7 @@ html.light #tt em {
|
|||
overflow-wrap: break-word;
|
||||
word-wrap: break-word; /*ie*/
|
||||
}
|
||||
html.light .mdo a,
|
||||
.mdo a {
|
||||
color: #fff;
|
||||
background: #39b;
|
||||
|
|
Loading…
Reference in a new issue