Skip to content

Commit c1e051b

Browse files
committed
fix(nextcloud): Workaround WebDAV CSRF bug on web
Signed-off-by: provokateurin <kate@provokateurin.de>
1 parent 7975430 commit c1e051b

File tree

2 files changed

+29
-0
lines changed

2 files changed

+29
-0
lines changed

.cspell/nextcloud.txt

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ partlycloudy
3333
productname
3434
rainshowers
3535
replyable
36+
requesttoken
3637
resharing
3738
rgdnvw
3839
setsip

packages/nextcloud/lib/src/webdav/client.dart

+28
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ import 'package:universal_io/io.dart' hide HttpClient;
1313
/// Base path used on the server
1414
final webdavBase = PathUri.parse('/remote.php/webdav');
1515

16+
// ignore: do_not_use_environment
17+
const bool _kIsWeb = bool.fromEnvironment('dart.library.js_util');
18+
1619
@internal
1720
class WebDavRequest extends http.BaseRequest {
1821
WebDavRequest(
@@ -55,6 +58,8 @@ class WebDavClient {
5558
// ignore: public_member_api_docs
5659
final DynamiteClient rootClient;
5760

61+
String? _token;
62+
5863
Future<http.StreamedResponse> _send(
5964
String method,
6065
Uri url, {
@@ -75,6 +80,29 @@ class WebDavClient {
7580
...?rootClient.authentications?.firstOrNull?.headers,
7681
});
7782

83+
// On web we need to send a CSRF token because we also send the cookies. In theory this should not be required as
84+
// long as we send the OCS-APIRequest header, but the server has a bug that only triggers when you also send the
85+
// cookies. On non-web platforms we don't send the cookies so we are fine, but on web the browser always does it
86+
// and therefore we need this workaround.
87+
// TODO: Fix this bug in server.
88+
if (_kIsWeb) {
89+
if (_token == null) {
90+
final response = await rootClient.httpClient.get(Uri.parse('${rootClient.baseURL}/index.php'));
91+
if (response.statusCode >= 300) {
92+
throw DynamiteStatusCodeException(
93+
response.statusCode,
94+
);
95+
}
96+
97+
_token = RegExp('data-requesttoken="([^"]*)"').firstMatch(response.body)!.group(1);
98+
}
99+
100+
request.headers.addAll({
101+
'OCS-APIRequest': 'true',
102+
'requesttoken': _token!,
103+
});
104+
}
105+
78106
final response = await rootClient.httpClient.send(request);
79107

80108
if (response.statusCode >= 300) {

0 commit comments

Comments
 (0)