copyparty 1.13.8__py3-none-any.whl → 1.14.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- copyparty/__main__.py +58 -2
- copyparty/__version__.py +3 -3
- copyparty/authsrv.py +224 -11
- copyparty/httpcli.py +183 -26
- copyparty/httpsrv.py +12 -2
- copyparty/svchub.py +77 -5
- copyparty/tcpsrv.py +19 -1
- copyparty/u2idx.py +19 -3
- copyparty/up2k.py +68 -13
- copyparty/util.py +1 -1
- copyparty/web/browser.css.gz +0 -0
- copyparty/web/browser.html +4 -4
- copyparty/web/browser.js.gz +0 -0
- copyparty/web/browser2.html +2 -2
- copyparty/web/md.html +2 -2
- copyparty/web/shares.css.gz +0 -0
- copyparty/web/shares.html +74 -0
- copyparty/web/shares.js.gz +0 -0
- copyparty/web/splash.css.gz +0 -0
- copyparty/web/splash.html +13 -6
- copyparty/web/splash.js.gz +0 -0
- copyparty/web/util.js.gz +0 -0
- {copyparty-1.13.8.dist-info → copyparty-1.14.1.dist-info}/METADATA +55 -3
- {copyparty-1.13.8.dist-info → copyparty-1.14.1.dist-info}/RECORD +28 -25
- {copyparty-1.13.8.dist-info → copyparty-1.14.1.dist-info}/WHEEL +1 -1
- {copyparty-1.13.8.dist-info → copyparty-1.14.1.dist-info}/LICENSE +0 -0
- {copyparty-1.13.8.dist-info → copyparty-1.14.1.dist-info}/entry_points.txt +0 -0
- {copyparty-1.13.8.dist-info → copyparty-1.14.1.dist-info}/top_level.txt +0 -0
copyparty/up2k.py
CHANGED
@@ -451,11 +451,17 @@ class Up2k(object):
|
|
451
451
|
cooldown = now + 3
|
452
452
|
# self.log("SR", 5)
|
453
453
|
|
454
|
-
if self.args.no_lifetime:
|
454
|
+
if self.args.no_lifetime and not self.args.shr:
|
455
455
|
timeout = now + 9001
|
456
456
|
else:
|
457
457
|
# important; not deferred by db_act
|
458
458
|
timeout = self._check_lifetimes()
|
459
|
+
try:
|
460
|
+
if self.args.shr:
|
461
|
+
timeout = min(self._check_shares(), timeout)
|
462
|
+
except Exception as ex:
|
463
|
+
t = "could not check for expiring shares: %r"
|
464
|
+
self.log(t % (ex,), 1)
|
459
465
|
|
460
466
|
try:
|
461
467
|
timeout = min(timeout, now + self._check_xiu())
|
@@ -558,6 +564,34 @@ class Up2k(object):
|
|
558
564
|
|
559
565
|
return timeout
|
560
566
|
|
567
|
+
def _check_shares(self) :
|
568
|
+
assert sqlite3 # type: ignore
|
569
|
+
|
570
|
+
now = time.time()
|
571
|
+
timeout = now + 9001
|
572
|
+
|
573
|
+
db = sqlite3.connect(self.args.shr_db, timeout=2)
|
574
|
+
cur = db.cursor()
|
575
|
+
|
576
|
+
q = "select k from sh where t1 and t1 <= ?"
|
577
|
+
rm = [x[0] for x in cur.execute(q, (now,))]
|
578
|
+
if rm:
|
579
|
+
self.log("forgetting expired shares %s" % (rm,))
|
580
|
+
q = "delete from sh where k=?"
|
581
|
+
cur.executemany(q, [(x,) for x in rm])
|
582
|
+
db.commit()
|
583
|
+
Daemon(self.hub._reload_blocking, "sharedrop", (False, False))
|
584
|
+
|
585
|
+
q = "select min(t1) from sh where t1 > 1"
|
586
|
+
(earliest,) = cur.execute(q).fetchone()
|
587
|
+
if earliest:
|
588
|
+
timeout = earliest - now
|
589
|
+
|
590
|
+
cur.close()
|
591
|
+
db.close()
|
592
|
+
|
593
|
+
return timeout
|
594
|
+
|
561
595
|
def _check_xiu(self) :
|
562
596
|
if self.xiu_busy:
|
563
597
|
return 2
|
@@ -2532,6 +2566,10 @@ class Up2k(object):
|
|
2532
2566
|
|
2533
2567
|
cur.connection.commit()
|
2534
2568
|
|
2569
|
+
def wake_rescanner(self):
|
2570
|
+
with self.rescan_cond:
|
2571
|
+
self.rescan_cond.notify_all()
|
2572
|
+
|
2535
2573
|
def handle_json(
|
2536
2574
|
self, cj , busy_aps
|
2537
2575
|
) :
|
@@ -2561,7 +2599,10 @@ class Up2k(object):
|
|
2561
2599
|
|
2562
2600
|
return ret
|
2563
2601
|
|
2564
|
-
def _handle_json(self, cj ) :
|
2602
|
+
def _handle_json(self, cj , depth = 1) :
|
2603
|
+
if depth > 16:
|
2604
|
+
raise Pebkac(500, "too many xbu relocs, giving up")
|
2605
|
+
|
2565
2606
|
ptop = cj["ptop"]
|
2566
2607
|
if not self.register_vpath(ptop, cj["vcfg"]):
|
2567
2608
|
if ptop not in self.registry:
|
@@ -2754,7 +2795,8 @@ class Up2k(object):
|
|
2754
2795
|
job = deepcopy(job)
|
2755
2796
|
job["wark"] = wark
|
2756
2797
|
job["at"] = cj.get("at") or time.time()
|
2757
|
-
|
2798
|
+
zs = "lmod ptop vtop prel name host user addr poke"
|
2799
|
+
for k in zs.split():
|
2758
2800
|
job[k] = cj.get(k) or ""
|
2759
2801
|
|
2760
2802
|
pdir = djoin(cj["ptop"], cj["prel"])
|
@@ -2791,12 +2833,18 @@ class Up2k(object):
|
|
2791
2833
|
if hr.get("reloc"):
|
2792
2834
|
x = pathmod(self.asrv.vfs, dst, vp, hr["reloc"])
|
2793
2835
|
if x:
|
2836
|
+
zvfs = vfs
|
2794
2837
|
pdir, _, job["name"], (vfs, rem) = x
|
2795
2838
|
dst = os.path.join(pdir, job["name"])
|
2839
|
+
job["vcfg"] = vfs.flags
|
2796
2840
|
job["ptop"] = vfs.realpath
|
2797
2841
|
job["vtop"] = vfs.vpath
|
2798
2842
|
job["prel"] = rem
|
2799
|
-
|
2843
|
+
if zvfs.vpath != vfs.vpath:
|
2844
|
+
# print(json.dumps(job, sort_keys=True, indent=4))
|
2845
|
+
job["hash"] = cj["hash"]
|
2846
|
+
self.log("xbu reloc1:%d..." % (depth,), 6)
|
2847
|
+
return self._handle_json(job, depth + 1)
|
2800
2848
|
|
2801
2849
|
job["name"] = self._untaken(pdir, job, now)
|
2802
2850
|
|
@@ -2877,7 +2925,9 @@ class Up2k(object):
|
|
2877
2925
|
lut.add(k)
|
2878
2926
|
|
2879
2927
|
try:
|
2880
|
-
self._new_upload(job)
|
2928
|
+
ret = self._new_upload(job, vfs, depth)
|
2929
|
+
if ret:
|
2930
|
+
return ret # xbu recursed
|
2881
2931
|
except:
|
2882
2932
|
self.registry[job["ptop"]].pop(job["wark"], None)
|
2883
2933
|
raise
|
@@ -4173,22 +4223,17 @@ class Up2k(object):
|
|
4173
4223
|
|
4174
4224
|
return ret
|
4175
4225
|
|
4176
|
-
def _new_upload(self, job )
|
4226
|
+
def _new_upload(self, job , vfs , depth ) :
|
4177
4227
|
pdir = djoin(job["ptop"], job["prel"])
|
4178
4228
|
if not job["size"]:
|
4179
4229
|
try:
|
4180
4230
|
inf = bos.stat(djoin(pdir, job["name"]))
|
4181
4231
|
if stat.S_ISREG(inf.st_mode):
|
4182
4232
|
job["lmod"] = inf.st_size
|
4183
|
-
return
|
4233
|
+
return {}
|
4184
4234
|
except:
|
4185
4235
|
pass
|
4186
4236
|
|
4187
|
-
self.registry[job["ptop"]][job["wark"]] = job
|
4188
|
-
job["name"] = self._untaken(pdir, job, job["t0"])
|
4189
|
-
# if len(job["name"].split(".")) > 8:
|
4190
|
-
# raise Exception("aaa")
|
4191
|
-
|
4192
4237
|
xbu = self.flags[job["ptop"]].get("xbu")
|
4193
4238
|
ap_chk = djoin(pdir, job["name"])
|
4194
4239
|
vp_chk = djoin(job["vtop"], job["prel"], job["name"])
|
@@ -4217,10 +4262,18 @@ class Up2k(object):
|
|
4217
4262
|
if hr.get("reloc"):
|
4218
4263
|
x = pathmod(self.asrv.vfs, ap_chk, vp_chk, hr["reloc"])
|
4219
4264
|
if x:
|
4265
|
+
zvfs = vfs
|
4220
4266
|
pdir, _, job["name"], (vfs, rem) = x
|
4267
|
+
job["vcfg"] = vfs.flags
|
4221
4268
|
job["ptop"] = vfs.realpath
|
4222
4269
|
job["vtop"] = vfs.vpath
|
4223
4270
|
job["prel"] = rem
|
4271
|
+
if zvfs.vpath != vfs.vpath:
|
4272
|
+
self.log("xbu reloc2:%d..." % (depth,), 6)
|
4273
|
+
return self._handle_json(job, depth + 1)
|
4274
|
+
|
4275
|
+
job["name"] = self._untaken(pdir, job, job["t0"])
|
4276
|
+
self.registry[job["ptop"]][job["wark"]] = job
|
4224
4277
|
|
4225
4278
|
tnam = job["name"] + ".PARTIAL"
|
4226
4279
|
if self.args.dotpart:
|
@@ -4230,7 +4283,7 @@ class Up2k(object):
|
|
4230
4283
|
job["tnam"] = tnam
|
4231
4284
|
if not job["hash"]:
|
4232
4285
|
del self.registry[job["ptop"]][job["wark"]]
|
4233
|
-
return
|
4286
|
+
return {}
|
4234
4287
|
|
4235
4288
|
if self.args.plain_ip:
|
4236
4289
|
dip = job["addr"].replace(":", ".")
|
@@ -4290,6 +4343,8 @@ class Up2k(object):
|
|
4290
4343
|
if not job["hash"]:
|
4291
4344
|
self._finish_upload(job["ptop"], job["wark"])
|
4292
4345
|
|
4346
|
+
return {}
|
4347
|
+
|
4293
4348
|
def _snapshot(self) :
|
4294
4349
|
slp = self.args.snap_wri
|
4295
4350
|
if not slp or self.args.no_snap:
|
copyparty/util.py
CHANGED
copyparty/web/browser.css.gz
CHANGED
Binary file
|
copyparty/web/browser.html
CHANGED
@@ -67,14 +67,14 @@
|
|
67
67
|
<div id="op_up2k" class="opview"></div>
|
68
68
|
|
69
69
|
<div id="op_cfg" class="opview opbox opwide"></div>
|
70
|
-
|
70
|
+
|
71
71
|
<h1 id="path">
|
72
72
|
<a href="#" id="entree">🌲</a>
|
73
73
|
{%- for n in vpnodes %}
|
74
74
|
<a href="{{ r }}/{{ n[0] }}">{{ n[1] }}</a>
|
75
75
|
{%- endfor %}
|
76
76
|
</h1>
|
77
|
-
|
77
|
+
|
78
78
|
<div id="tree"></div>
|
79
79
|
|
80
80
|
<div id="wrap">
|
@@ -118,11 +118,11 @@
|
|
118
118
|
|
119
119
|
</tbody>
|
120
120
|
</table>
|
121
|
-
|
121
|
+
|
122
122
|
<div id="epi" class="logue">{{ "" if sb_lg else logues[1] }}</div>
|
123
123
|
|
124
124
|
<h2 id="wfp"><a href="{{ r }}/?h" id="goh">control-panel</a></h2>
|
125
|
-
|
125
|
+
|
126
126
|
<a href="#" id="repl">π</a>
|
127
127
|
|
128
128
|
</div>
|
copyparty/web/browser.js.gz
CHANGED
Binary file
|
copyparty/web/browser2.html
CHANGED
copyparty/web/md.html
CHANGED
@@ -49,7 +49,7 @@
|
|
49
49
|
<div id="mp" class="mdo"></div>
|
50
50
|
</div>
|
51
51
|
<a href="#" id="repl">π</a>
|
52
|
-
|
52
|
+
|
53
53
|
{%- if edit %}
|
54
54
|
<div id="helpbox">
|
55
55
|
<textarea autocomplete="off">
|
@@ -125,7 +125,7 @@ write markdown (most html is 🙆 too)
|
|
125
125
|
</textarea>
|
126
126
|
</div>
|
127
127
|
{%- endif %}
|
128
|
-
|
128
|
+
|
129
129
|
<script>
|
130
130
|
|
131
131
|
var SR = {{ r|tojson }},
|
Binary file
|
@@ -0,0 +1,74 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
3
|
+
|
4
|
+
<head>
|
5
|
+
<meta charset="utf-8">
|
6
|
+
<title>{{ s_doctitle }}</title>
|
7
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
8
|
+
<meta name="viewport" content="width=device-width, initial-scale=0.8">
|
9
|
+
<meta name="theme-color" content="#{{ tcolor }}">
|
10
|
+
<link rel="stylesheet" media="screen" href="{{ r }}/.cpr/shares.css?_={{ ts }}">
|
11
|
+
<link rel="stylesheet" media="screen" href="{{ r }}/.cpr/ui.css?_={{ ts }}">
|
12
|
+
{{ html_head }}
|
13
|
+
</head>
|
14
|
+
|
15
|
+
<body>
|
16
|
+
<div id="wrap">
|
17
|
+
<a id="a" href="{{ r }}/?shares" class="af">refresh</a>
|
18
|
+
<a id="a" href="{{ r }}/?h" class="af">controlpanel</a>
|
19
|
+
|
20
|
+
<span>axs = perms (read,write,move,delet)</span>
|
21
|
+
<span>st 1=file 2=dir</span>
|
22
|
+
<span>min/hrs = time left</span>
|
23
|
+
|
24
|
+
<table><tr>
|
25
|
+
<th>delete</th>
|
26
|
+
<th>sharekey</th>
|
27
|
+
<th>pw</th>
|
28
|
+
<th>source</th>
|
29
|
+
<th>axs</th>
|
30
|
+
<th>st</th>
|
31
|
+
<th>user</th>
|
32
|
+
<th>created</th>
|
33
|
+
<th>expires</th>
|
34
|
+
<th>min</th>
|
35
|
+
<th>hrs</th>
|
36
|
+
</tr>
|
37
|
+
{% for k, pw, vp, pr, st, un, t0, t1 in rows %}
|
38
|
+
<tr>
|
39
|
+
<td><a href="#" k="{{ k }}">delete</a></td>
|
40
|
+
<td><a href="{{ r }}{{ shr }}{{ k }}">{{ k }}</a></td>
|
41
|
+
<td>{{ pw }}</td>
|
42
|
+
<td><a href="{{ r }}/{{ vp|e }}">{{ vp|e }}</a></td>
|
43
|
+
<td>{{ pr }}</td>
|
44
|
+
<td>{{ st }}</td>
|
45
|
+
<td>{{ un|e }}</td>
|
46
|
+
<td>{{ t0 }}</td>
|
47
|
+
<td>{{ t1 }}</td>
|
48
|
+
<td>{{ (t1 - now) // 60 if t1 else "never" }}</td>
|
49
|
+
<td>{{ (t1 - now) // 3600 if t1 else "never" }}</td>
|
50
|
+
</tr>
|
51
|
+
{% endfor %}
|
52
|
+
</table>
|
53
|
+
{% if not rows %}
|
54
|
+
(you don't have any active shares btw)
|
55
|
+
{% endif %}
|
56
|
+
<script>
|
57
|
+
|
58
|
+
var SR = {{ r|tojson }},
|
59
|
+
shr="{{ shr }}",
|
60
|
+
lang="{{ lang }}",
|
61
|
+
dfavico="{{ favico }}";
|
62
|
+
|
63
|
+
var STG = window.localStorage;
|
64
|
+
document.documentElement.className = (STG && STG.cpp_thm) || "{{ this.args.theme }}";
|
65
|
+
|
66
|
+
</script>
|
67
|
+
<script src="{{ r }}/.cpr/util.js?_={{ ts }}"></script>
|
68
|
+
<script src="{{ r }}/.cpr/shares.js?_={{ ts }}"></script>
|
69
|
+
{%- if js %}
|
70
|
+
<script src="{{ js }}_={{ ts }}"></script>
|
71
|
+
{%- endif %}
|
72
|
+
</body>
|
73
|
+
</html>
|
74
|
+
|
Binary file
|
copyparty/web/splash.css.gz
CHANGED
Binary file
|
copyparty/web/splash.html
CHANGED
@@ -21,7 +21,7 @@
|
|
21
21
|
<p id="b">howdy stranger <small>(you're not logged in)</small></p>
|
22
22
|
{%- else %}
|
23
23
|
<a id="c" href="{{ r }}/?pw=x" class="logout">logout</a>
|
24
|
-
<p><span id="m">welcome back,</span> <strong>{{ this.uname }}</strong></p>
|
24
|
+
<p><span id="m">welcome back,</span> <strong>{{ this.uname|e }}</strong></p>
|
25
25
|
{%- endif %}
|
26
26
|
|
27
27
|
{%- if msg %}
|
@@ -76,8 +76,12 @@
|
|
76
76
|
</ul>
|
77
77
|
{%- endif %}
|
78
78
|
|
79
|
-
<h1 id="cc">
|
79
|
+
<h1 id="cc">other stuff:</h1>
|
80
80
|
<ul>
|
81
|
+
{%- if this.uname != '*' and this.args.shr %}
|
82
|
+
<li><a id="y" href="{{ r }}/?shares">edit shares</a></li>
|
83
|
+
{% endif %}
|
84
|
+
|
81
85
|
{% if k304 or k304vis %}
|
82
86
|
{% if k304 %}
|
83
87
|
<li><a id="h" href="{{ r }}/?k304=n">disable k304</a> (currently enabled)
|
@@ -92,11 +96,14 @@
|
|
92
96
|
|
93
97
|
<h1 id="l">login for more:</h1>
|
94
98
|
<div>
|
95
|
-
<form method="post" enctype="multipart/form-data" action="{{ r }}/{{ qvpath }}">
|
96
|
-
<input type="hidden" name="act" value="login" />
|
97
|
-
<input type="password" name="cppwd" placeholder=" password" />
|
99
|
+
<form id="lf" method="post" enctype="multipart/form-data" action="{{ r }}/{{ qvpath }}">
|
100
|
+
<input type="hidden" id="la" name="act" value="login" />
|
101
|
+
<input type="password" id="lp" name="cppwd" placeholder=" password" />
|
98
102
|
<input type="hidden" name="uhash" id="uhash" value="x" />
|
99
|
-
<input type="submit" value="Login" />
|
103
|
+
<input type="submit" id="ls" value="Login" />
|
104
|
+
{% if chpw %}
|
105
|
+
<a id="x" href="#">change password</a>
|
106
|
+
{% endif %}
|
100
107
|
{% if ahttps %}
|
101
108
|
<a id="w" href="{{ ahttps }}">switch to https</a>
|
102
109
|
{% endif %}
|
copyparty/web/splash.js.gz
CHANGED
Binary file
|
copyparty/web/util.js.gz
CHANGED
Binary file
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: copyparty
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.14.1
|
4
4
|
Summary: Portable file server with accelerated resumable uploads, deduplication, WebDAV, FTP, zeroconf, media indexer, video thumbnails, audio transcoding, and write-only folders
|
5
5
|
Author-email: ed <copyparty@ocv.me>
|
6
6
|
License: MIT
|
@@ -96,6 +96,7 @@ turn almost any device into a file server with resumable uploads/downloads using
|
|
96
96
|
* [self-destruct](#self-destruct) - uploads can be given a lifetime
|
97
97
|
* [race the beam](#race-the-beam) - download files while they're still uploading ([demo video](http://a.ocv.me/pub/g/nerd-stuff/cpp/2024-0418-race-the-beam.webm))
|
98
98
|
* [file manager](#file-manager) - cut/paste, rename, and delete files/folders (if you have permission)
|
99
|
+
* [shares](#shares) - share a file or folder by creating a temporary link
|
99
100
|
* [batch rename](#batch-rename) - select some files and press `F2` to bring up the rename UI
|
100
101
|
* [media player](#media-player) - plays almost every audio format there is
|
101
102
|
* [audio equalizer](#audio-equalizer) - and [dynamic range compressor](https://en.wikipedia.org/wiki/Dynamic_range_compression)
|
@@ -130,6 +131,7 @@ turn almost any device into a file server with resumable uploads/downloads using
|
|
130
131
|
* [upload events](#upload-events) - the older, more powerful approach ([examples](./bin/mtag/))
|
131
132
|
* [handlers](#handlers) - redefine behavior with plugins ([examples](./bin/handlers/))
|
132
133
|
* [identity providers](#identity-providers) - replace copyparty passwords with oauth and such
|
134
|
+
* [user-changeable passwords](#user-changeable-passwords) - if permitted, users can change their own passwords
|
133
135
|
* [using the cloud as storage](#using-the-cloud-as-storage) - connecting to an aws s3 bucket and similar
|
134
136
|
* [hiding from google](#hiding-from-google) - tell search engines you dont wanna be indexed
|
135
137
|
* [themes](#themes)
|
@@ -798,6 +800,33 @@ file selection: click somewhere on the line (not the link itsef), then:
|
|
798
800
|
you can move files across browser tabs (cut in one tab, paste in another)
|
799
801
|
|
800
802
|
|
803
|
+
## shares
|
804
|
+
|
805
|
+
share a file or folder by creating a temporary link
|
806
|
+
|
807
|
+
when enabled in the server settings (`--shr`), click the bottom-right `share` button to share the folder you're currently in, or select a file first to share only that file
|
808
|
+
|
809
|
+
this feature was made with [identity providers](#identity-providers) in mind -- configure your reverseproxy to skip the IdP's access-control for a given URL prefix and use that to safely share specific files/folders sans the usual auth checks
|
810
|
+
|
811
|
+
when creating a share, the creator can choose any of the following options:
|
812
|
+
|
813
|
+
* password-protection
|
814
|
+
* expire after a certain time
|
815
|
+
* allow visitors to upload (if the user who creates the share has write-access)
|
816
|
+
|
817
|
+
semi-intentional limitations:
|
818
|
+
|
819
|
+
* cleanup of expired shares only works when global option `e2d` is set, and/or at least one volume on the server has volflag `e2d`
|
820
|
+
* only folders from the same volume are shared; if you are sharing a folder which contains other volumes, then the contents of those volumes will not be available
|
821
|
+
* no option to "delete after first access" because tricky
|
822
|
+
* when linking something to discord (for example) it'll get accessed by their scraper and that would count as a hit
|
823
|
+
* browsers wouldn't be able to resume a broken download unless the requester's IP gets allowlisted for X minutes (ref. tricky)
|
824
|
+
|
825
|
+
the links are created inside a specific toplevel folder which must be specified with server-config `--shr`, for example `--shr /share/` (this also enables the feature)
|
826
|
+
|
827
|
+
users can delete their own shares in the controlpanel, and a list of privileged users (`--shr-adm`) are allowed to see and/or delet any share on the server
|
828
|
+
|
829
|
+
|
801
830
|
## batch rename
|
802
831
|
|
803
832
|
select some files and press `F2` to bring up the rename UI
|
@@ -1409,6 +1438,29 @@ there is a [docker-compose example](./docs/examples/docker/idp-authelia-traefik)
|
|
1409
1438
|
|
1410
1439
|
a more complete example of the copyparty configuration options [look like this](./docs/examples/docker/idp/copyparty.conf)
|
1411
1440
|
|
1441
|
+
but if you just want to let users change their own passwords, then you probably want [user-changeable passwords](#user-changeable-passwords) instead
|
1442
|
+
|
1443
|
+
|
1444
|
+
## user-changeable passwords
|
1445
|
+
|
1446
|
+
if permitted, users can change their own passwords in the control-panel
|
1447
|
+
|
1448
|
+
* not compatible with [identity providers](#identity-providers)
|
1449
|
+
|
1450
|
+
* must be enabled with `--chpw` because account-sharing is a popular usecase
|
1451
|
+
|
1452
|
+
* if you want to enable the feature but deny password-changing for a specific list of accounts, you can do that with `--chpw-no name1,name2,name3,...`
|
1453
|
+
|
1454
|
+
* to perform a password reset, edit the server config and give the user another password there, then do a [config reload](#server-config) or server restart
|
1455
|
+
|
1456
|
+
* the custom passwords are kept in a textfile at filesystem-path `--chpw-db`, by default `chpw.json` in the copyparty config folder
|
1457
|
+
|
1458
|
+
* if you run multiple copyparty instances with different users you *almost definitely* want to specify separate DBs for each instance
|
1459
|
+
|
1460
|
+
* if [password hashing](#password-hashing) is enbled, the passwords in the db are also hashed
|
1461
|
+
|
1462
|
+
* ...which means that all user-defined passwords will be forgotten if you change password-hashing settings
|
1463
|
+
|
1412
1464
|
|
1413
1465
|
## using the cloud as storage
|
1414
1466
|
|
@@ -1513,7 +1565,7 @@ some reverse proxies (such as [Caddy](https://caddyserver.com/)) can automatical
|
|
1513
1565
|
* **warning:** nginx-QUIC (HTTP/3) is still experimental and can make uploads much slower, so HTTP/1.1 is recommended for now
|
1514
1566
|
* depending on server/client, HTTP/1.1 can also be 5x faster than HTTP/2
|
1515
1567
|
|
1516
|
-
for improved security (and a
|
1568
|
+
for improved security (and a 10% performance boost) consider listening on a unix-socket with `-i unix:770:www:/tmp/party.sock` (permission `770` means only members of group `www` can access it)
|
1517
1569
|
|
1518
1570
|
example webserver configs:
|
1519
1571
|
|
@@ -1954,7 +2006,7 @@ some notes on hardening
|
|
1954
2006
|
* cors doesn't work right otherwise
|
1955
2007
|
* if you allow anonymous uploads or otherwise don't trust the contents of a volume, you can prevent XSS with volflag `nohtml`
|
1956
2008
|
* this returns html documents as plaintext, and also disables markdown rendering
|
1957
|
-
* when running behind a reverse-proxy, listen on a unix-socket
|
2009
|
+
* when running behind a reverse-proxy, listen on a unix-socket for tighter access control (and more performance); see [reverse-proxy](#reverse-proxy) or `--help-bind`
|
1958
2010
|
|
1959
2011
|
safety profiles:
|
1960
2012
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
copyparty/__init__.py,sha256=fUINM1abqDGzCCH_JcXdOnLdKOV-SrTI2Xo2QgQW2P4,1703
|
2
|
-
copyparty/__main__.py,sha256
|
3
|
-
copyparty/__version__.py,sha256=
|
4
|
-
copyparty/authsrv.py,sha256=
|
2
|
+
copyparty/__main__.py,sha256=JBSVuRhMEnI_LMdRe5VLs09Li7WRJFcLlYGStcu0F90,107832
|
3
|
+
copyparty/__version__.py,sha256=dTu12M9eISQGxeta4ssAuHyXgdmB0G1mXgoIPbzdzt8,258
|
4
|
+
copyparty/authsrv.py,sha256=5LEz9yBB4PGEgbVsnJne-XevAsHbolFP-yfanOsDsUs,94305
|
5
5
|
copyparty/broker_mp.py,sha256=YFe1S6Zziht8Qc__dCLj_ff8z0DDny9lqk_Mi5ajsJk,3868
|
6
6
|
copyparty/broker_mpw.py,sha256=4ZI7bJYOwUibeAJVv9_FPGNmHrr9eOtkj_Kz0JEppTU,3197
|
7
7
|
copyparty/broker_thr.py,sha256=eKr--HJGig5zqvNGwH9UoBG9Nvi9mT2axrRmJwknd0s,1759
|
@@ -11,9 +11,9 @@ copyparty/cfg.py,sha256=i8-bjWgbguQooxiA172RcptqR_SEOwDHJ4cqldrZ8oQ,9792
|
|
11
11
|
copyparty/dxml.py,sha256=lZpg-kn-kQsXRtNY1n6fRaS-b7uXzMCyv8ovKnhZcZc,1548
|
12
12
|
copyparty/fsutil.py,sha256=hnEHgySI43-XJJKbI8n6t1A6oVHzR_nYdsBcAwtreBk,4610
|
13
13
|
copyparty/ftpd.py,sha256=1vD-KTy07xfEEEk1dx37pUYModpNO2gIhVXvFUr205M,17497
|
14
|
-
copyparty/httpcli.py,sha256=
|
14
|
+
copyparty/httpcli.py,sha256=xk8ZjiZkb3Cko-_A95bgFgm68rpHrmASLwqRmlOss1U,180620
|
15
15
|
copyparty/httpconn.py,sha256=mwIDup85cBowIfJOse8rla5bqTz7nf-ChgfR-5-V0JM,6938
|
16
|
-
copyparty/httpsrv.py,sha256=
|
16
|
+
copyparty/httpsrv.py,sha256=8_1Ivg3eco7HJDjqL_rUB58IOUaUnoXGhO62bOMXLBk,17242
|
17
17
|
copyparty/ico.py,sha256=eWSxEae4wOCfheHl-m-wchYvFRAR_97kJDb4NGaB-Z8,3561
|
18
18
|
copyparty/mdns.py,sha256=vC078llnL1v0pvL3mnwacuStFHPJUQuxo9Opj-IbHL4,18155
|
19
19
|
copyparty/metrics.py,sha256=O8qiPNDxNjub_PI8C8Qu9rBQ_z0J1mnKonqkcTeAtf4,8845
|
@@ -24,15 +24,15 @@ copyparty/smbd.py,sha256=8zkC9BjVtGiKXMLajbdakxoKeFzACdM75SW0_SvqXJA,14490
|
|
24
24
|
copyparty/ssdp.py,sha256=8iyF5sqIjATJLWcAtnJa8eadHosOn0CP4ywltzJ7bVY,7023
|
25
25
|
copyparty/star.py,sha256=tV5BbX6AiQ7N4UU8DYtSTckNYeoeey4DBqq4LjfymbY,3818
|
26
26
|
copyparty/sutil.py,sha256=JTMrQwcWH85hXB_cKG206eDZ967WZDGaP00AWvl_gB0,3214
|
27
|
-
copyparty/svchub.py,sha256=
|
27
|
+
copyparty/svchub.py,sha256=eAvlDGhKAXUYxAHd03lHY-iNat32Bbt1rZHZwF46Kzg,37367
|
28
28
|
copyparty/szip.py,sha256=tor4yjdHhEL4Ox-Xg7-cuUFrMO0IwQD29aRX5Cp8MYs,8605
|
29
|
-
copyparty/tcpsrv.py,sha256=
|
29
|
+
copyparty/tcpsrv.py,sha256=jM_Za64O8LEMfMrU4irJluIJZrU494e2b759r_KhaUQ,19881
|
30
30
|
copyparty/tftpd.py,sha256=i1-oZ05DJq2_nDOW3g3PfTkMoUCr2lAcDYFMWArwtKA,13568
|
31
31
|
copyparty/th_cli.py,sha256=o6FMkerYvAXS455z3DUossVztu_nzFlYSQhs6qN6Jt8,4636
|
32
32
|
copyparty/th_srv.py,sha256=27IftjIXUQzRRiUytt-CgXkybEoP3HHHoXaDAvxEmLo,29217
|
33
|
-
copyparty/u2idx.py,sha256=
|
34
|
-
copyparty/up2k.py,sha256=
|
35
|
-
copyparty/util.py,sha256=
|
33
|
+
copyparty/u2idx.py,sha256=t4mzjj2GDrkjIHt0RM68y1EgT5qOBoz6mkYgjMbqA38,13526
|
34
|
+
copyparty/up2k.py,sha256=Ys3tbEm4RW4FLxaFwrdgG7RSsDd0Hr2832I0nCvLtfM,153049
|
35
|
+
copyparty/util.py,sha256=S7FuQBPbl2FX7ULIH9VNgiB7Z_rceqTJssXz4SGErwA,88625
|
36
36
|
copyparty/bos/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
37
37
|
copyparty/bos/bos.py,sha256=Wb7eWsXJgR5AFlBR9ZOyKrLTwy-Kct9RrGiOu4Jo37Y,1622
|
38
38
|
copyparty/bos/path.py,sha256=yEjCq2ki9CvxA5sCT8pS0keEXwugs0ZeUyUhdBziOCI,777
|
@@ -55,14 +55,14 @@ copyparty/stolen/ifaddr/_posix.py,sha256=-67NdfGrCktfQPakT2fLbjl2U00QMvyBGkSvrUu
|
|
55
55
|
copyparty/stolen/ifaddr/_shared.py,sha256=uNC4SdEIgdSLKvuUzsf1aM-H1Xrc_9mpLoOT43YukGs,6206
|
56
56
|
copyparty/stolen/ifaddr/_win32.py,sha256=EE-QyoBgeB7lYQ6z62VjXNaRozaYfCkaJBHGNA8QtZM,4026
|
57
57
|
copyparty/web/baguettebox.js.gz,sha256=4dS8-r4si84ca71l98672ahnRI86Aq95MU-bc5knykk,7962
|
58
|
-
copyparty/web/browser.css.gz,sha256=
|
59
|
-
copyparty/web/browser.html,sha256
|
60
|
-
copyparty/web/browser.js.gz,sha256
|
61
|
-
copyparty/web/browser2.html,sha256=
|
58
|
+
copyparty/web/browser.css.gz,sha256=tE4SKTvB2l6t91Mb_bhadKbV0QMLrYbAcVE-JQ7MPUk,11494
|
59
|
+
copyparty/web/browser.html,sha256=vvfWiu_aOFRar8u5lridMRKQSPF4R0YkA41zrsh82Qs,4878
|
60
|
+
copyparty/web/browser.js.gz,sha256=lF2coe19rlOIwgDZlcqdnascDjqCJDVzVxtyZopQE2Y,71016
|
61
|
+
copyparty/web/browser2.html,sha256=NRUZ08GH-e2YcGXcoz0UjYg6JIVF42u4IMX4HHwWTmg,1587
|
62
62
|
copyparty/web/cf.html,sha256=lJThtNFNAQT1ClCHHlivAkDGE0LutedwopXD62Z8Nys,589
|
63
63
|
copyparty/web/dbg-audio.js.gz,sha256=Ma-KZtK8LnmiwNvNKFKXMPYl_Nn_3U7GsJ6-DRWC2HE,688
|
64
64
|
copyparty/web/md.css.gz,sha256=UZpN0J7ubVM05CZkbZYkQRJeGgJt_GNDEzKTGSQd8h4,2032
|
65
|
-
copyparty/web/md.html,sha256=
|
65
|
+
copyparty/web/md.html,sha256=isNbIzWbp_oqkhQSXm0uf3st3h4uB3LLTXFcHHcvgPQ,4189
|
66
66
|
copyparty/web/md.js.gz,sha256=AHRQ3a-PZq_UiGh4CjNwXRllJCvA0IqqYmeHhFWhCig,4179
|
67
67
|
copyparty/web/md2.css.gz,sha256=uIVHKScThdbcfhXNSHgKZnALYpxbnXC-WuEzOJ20Lpc,699
|
68
68
|
copyparty/web/md2.js.gz,sha256=0fTA3lahQ1iDvJR4Q3W9v8dX5hc5VP8nunTtoDwFySs,8363
|
@@ -71,14 +71,17 @@ copyparty/web/mde.html,sha256=ImBhQAaEUCke2M85QU_fl4X2XQExRLcEzgCEN8RNe9o,1759
|
|
71
71
|
copyparty/web/mde.js.gz,sha256=kN2eUSvr4mFuksfK4-4LimJmWdwsao39Sea2lWtu8L0,2224
|
72
72
|
copyparty/web/msg.css.gz,sha256=u90fXYAVrMD-jqwf5XFVC1ptSpSHZUe8Mez6PX101P8,300
|
73
73
|
copyparty/web/msg.html,sha256=w9CM3hkLLGJX9fWEaG4gSbTOPe2GcPqW8BpSCDiFzOI,977
|
74
|
-
copyparty/web/
|
75
|
-
copyparty/web/
|
76
|
-
copyparty/web/
|
74
|
+
copyparty/web/shares.css.gz,sha256=4OqsDr0aby14LPy61nU6JdEsgDyBw3TMQiClLvOPFds,477
|
75
|
+
copyparty/web/shares.html,sha256=sogrhA6HCzG413qSrHar8-RFSocuBxACTWArO_HOP28,2208
|
76
|
+
copyparty/web/shares.js.gz,sha256=PYOZ2jjzDTy_g7lali1kozUjUoI-97LsjXxKUzoThiU,319
|
77
|
+
copyparty/web/splash.css.gz,sha256=lCleyzwvc5KdkFtuLhImeOeRZKYi_ISiLppCDcmRK7Y,1023
|
78
|
+
copyparty/web/splash.html,sha256=FDCcWzO8E_mm_D4EaCWgeMyFSkMTAnGxWwPh9dn1e4Y,4221
|
79
|
+
copyparty/web/splash.js.gz,sha256=RUH5mxrYtCAQ4eLsOUfLl0ryHa1f6-kf_I2j8FitMB0,1840
|
77
80
|
copyparty/web/svcs.html,sha256=v0C3cOFWXYlvp3GEifz1Qj0W3MD8JANT3WTON05GZ9o,11797
|
78
81
|
copyparty/web/svcs.js.gz,sha256=k81ZvZ3I-f4fMHKrNGGOgOlvXnCBz0mVjD-8mieoWCA,520
|
79
82
|
copyparty/web/ui.css.gz,sha256=GnR_PxnZGcNs2IJnb5hFffnhlW3cUHkPad3tNIm-7DQ,2637
|
80
83
|
copyparty/web/up2k.js.gz,sha256=KufMtRViAZQo2rVj67iEWbdPxlVeXW85emRYVJoY3aA,22946
|
81
|
-
copyparty/web/util.js.gz,sha256=
|
84
|
+
copyparty/web/util.js.gz,sha256=9LeqbO0j_Z4pEXH2pl9FxWxv5eG7d-SE997AFGboK74,14682
|
82
85
|
copyparty/web/w.hash.js.gz,sha256=7wP9EZQNXQxwZnCCFUVsi_-6TM9PLZJeZ9krutXRRj8,1060
|
83
86
|
copyparty/web/a/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
84
87
|
copyparty/web/a/partyfuse.py,sha256=MuRkaSuYsdfWfBFMOkbPwDXqSvNTw3sd7QhhlKCDZ8I,32311
|
@@ -102,9 +105,9 @@ copyparty/web/deps/prismd.css.gz,sha256=ObUlksQVr-OuYlTz-I4B23TeBg2QDVVGRnWBz8cV
|
|
102
105
|
copyparty/web/deps/scp.woff2,sha256=w99BDU5i8MukkMEL-iW0YO9H4vFFZSPWxbkH70ytaAg,8612
|
103
106
|
copyparty/web/deps/sha512.ac.js.gz,sha256=lFZaCLumgWxrvEuDr4bqdKHsqjX82AbVAb7_F45Yk88,7033
|
104
107
|
copyparty/web/deps/sha512.hw.js.gz,sha256=vqoXeracj-99Z5MfY3jK2N4WiSzYQdfjy0RnUlQDhSU,8110
|
105
|
-
copyparty-1.
|
106
|
-
copyparty-1.
|
107
|
-
copyparty-1.
|
108
|
-
copyparty-1.
|
109
|
-
copyparty-1.
|
110
|
-
copyparty-1.
|
108
|
+
copyparty-1.14.1.dist-info/LICENSE,sha256=gOr4h33pCsBEg9uIy9AYmb7qlocL4V9t2uPJS5wllr0,1072
|
109
|
+
copyparty-1.14.1.dist-info/METADATA,sha256=AXs4o0mUOTU-WVhn3Kh5QyI-swMa36Rqrk3a4v1Gp38,130962
|
110
|
+
copyparty-1.14.1.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
|
111
|
+
copyparty-1.14.1.dist-info/entry_points.txt,sha256=4zw6a3rqASywQomiYLObjjlxybaI65LYYOTJwgKz7b0,128
|
112
|
+
copyparty-1.14.1.dist-info/top_level.txt,sha256=LnYUPsDyk-8kFgM6YJLG4h820DQekn81cObKSu9g-sI,10
|
113
|
+
copyparty-1.14.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|