From c08ab81334e7508b87dc514efdf4b02fb18f6c55 Mon Sep 17 00:00:00 2001 From: Luka Trovic Date: Wed, 20 Mar 2024 21:08:54 +0100 Subject: [PATCH 1/3] fix: csrf check failed on public share with password Signed-off-by: Luka Trovic --- core/js/publicshareauth.js | 15 +++++++++++++++ core/src/OC/index.js | 2 ++ core/src/OC/requesttoken.js | 16 ++++++++++++++++ core/templates/publicshareauth.php | 10 +++++----- 4 files changed, 38 insertions(+), 5 deletions(-) diff --git a/core/js/publicshareauth.js b/core/js/publicshareauth.js index 3d694c7bfd6aa..c0df3de3d9227 100644 --- a/core/js/publicshareauth.js +++ b/core/js/publicshareauth.js @@ -52,3 +52,18 @@ document.addEventListener('DOMContentLoaded', function() { } }); + +// Fix error "CSRF check failed" +document.addEventListener('DOMContentLoaded', function() { + var form = document.getElementById('password-input-form'); + if (form) { + form.addEventListener('submit', async function(event) { + event.preventDefault(); + var requestToken = document.getElementById('requesttoken'); + if (requestToken) { + requestToken.value = await OC.fetchRequestToken(); + } + form.submit(); + }); + } +}); diff --git a/core/src/OC/index.js b/core/src/OC/index.js index 33dd45a17ee69..34af0b25522e8 100644 --- a/core/src/OC/index.js +++ b/core/src/OC/index.js @@ -70,6 +70,7 @@ import { } from './host.js' import { getToken as getRequestToken, + fetchToken as fetchRequestToken, } from './requesttoken.js' import { hideMenus, @@ -274,6 +275,7 @@ export default { redirect, reload, requestToken: getRequestToken(), + fetchRequestToken, /** * @deprecated 19.0.0 use `linkTo` from https://www.npmjs.com/package/@nextcloud/router */ diff --git a/core/src/OC/requesttoken.js b/core/src/OC/requesttoken.js index eba15e88e081a..229f8ff0370ed 100644 --- a/core/src/OC/requesttoken.js +++ b/core/src/OC/requesttoken.js @@ -22,6 +22,8 @@ */ import { emit } from '@nextcloud/event-bus' +import { generateUrl } from '@nextcloud/router' +import $ from 'jquery' /** * @private @@ -41,6 +43,15 @@ export const manageToken = (global, emit) => { token, }) }, + fetchToken: async () => { + const url = generateUrl('/csrftoken') + const resp = await $.get(url) + token = resp.token + emit('csrf-token-update', { + token, + }) + return token + }, } } @@ -55,3 +66,8 @@ export const getToken = manageFromDocument.getToken * @param {string} newToken new token */ export const setToken = manageFromDocument.setToken + +/** + * @return {Promise} + */ +export const fetchToken = manageFromDocument.fetchToken diff --git a/core/templates/publicshareauth.php b/core/templates/publicshareauth.php index a48bbbbb7b2b5..3b7393e0c07c9 100644 --- a/core/templates/publicshareauth.php +++ b/core/templates/publicshareauth.php @@ -22,7 +22,7 @@

- +

- +
@@ -46,7 +46,7 @@ class="svg icon-confirm input-button-inline" value="" disabled="disabled" />

- +

@@ -59,12 +59,12 @@ class="svg icon-confirm input-button-inline" value="" disabled="disabled" />
- + getShareType() === $_['share']::TYPE_EMAIL && !$_['share']->getSendPasswordByTalk()): ?> t('Forgot password?')); ?> - +
From 945828bf4c53dfa65bea31191bbf71e8ffbe691e Mon Sep 17 00:00:00 2001 From: Luka Trovic Date: Mon, 25 Mar 2024 21:33:30 +0100 Subject: [PATCH 2/3] fix: csrf check failed on public share with password Signed-off-by: Luka Trovic --- core/js/publicshareauth.js | 15 --------------- core/src/OC/index.js | 2 -- core/src/OC/requesttoken.js | 16 ---------------- core/src/main.js | 19 +++++++++++++++++++ 4 files changed, 19 insertions(+), 33 deletions(-) diff --git a/core/js/publicshareauth.js b/core/js/publicshareauth.js index c0df3de3d9227..3d694c7bfd6aa 100644 --- a/core/js/publicshareauth.js +++ b/core/js/publicshareauth.js @@ -52,18 +52,3 @@ document.addEventListener('DOMContentLoaded', function() { } }); - -// Fix error "CSRF check failed" -document.addEventListener('DOMContentLoaded', function() { - var form = document.getElementById('password-input-form'); - if (form) { - form.addEventListener('submit', async function(event) { - event.preventDefault(); - var requestToken = document.getElementById('requesttoken'); - if (requestToken) { - requestToken.value = await OC.fetchRequestToken(); - } - form.submit(); - }); - } -}); diff --git a/core/src/OC/index.js b/core/src/OC/index.js index 34af0b25522e8..33dd45a17ee69 100644 --- a/core/src/OC/index.js +++ b/core/src/OC/index.js @@ -70,7 +70,6 @@ import { } from './host.js' import { getToken as getRequestToken, - fetchToken as fetchRequestToken, } from './requesttoken.js' import { hideMenus, @@ -275,7 +274,6 @@ export default { redirect, reload, requestToken: getRequestToken(), - fetchRequestToken, /** * @deprecated 19.0.0 use `linkTo` from https://www.npmjs.com/package/@nextcloud/router */ diff --git a/core/src/OC/requesttoken.js b/core/src/OC/requesttoken.js index 229f8ff0370ed..eba15e88e081a 100644 --- a/core/src/OC/requesttoken.js +++ b/core/src/OC/requesttoken.js @@ -22,8 +22,6 @@ */ import { emit } from '@nextcloud/event-bus' -import { generateUrl } from '@nextcloud/router' -import $ from 'jquery' /** * @private @@ -43,15 +41,6 @@ export const manageToken = (global, emit) => { token, }) }, - fetchToken: async () => { - const url = generateUrl('/csrftoken') - const resp = await $.get(url) - token = resp.token - emit('csrf-token-update', { - token, - }) - return token - }, } } @@ -66,8 +55,3 @@ export const getToken = manageFromDocument.getToken * @param {string} newToken new token */ export const setToken = manageFromDocument.setToken - -/** - * @return {Promise} - */ -export const fetchToken = manageFromDocument.fetchToken diff --git a/core/src/main.js b/core/src/main.js index 44241ad3bb4ff..a4535769145ac 100644 --- a/core/src/main.js +++ b/core/src/main.js @@ -35,6 +35,8 @@ import './jquery/index.js' import { initCore } from './init.js' import { registerAppsSlideToggle } from './OC/apps.js' import { getRequestToken } from '@nextcloud/auth' +import { generateUrl } from '@nextcloud/router' +import Axios from '@nextcloud/axios' // eslint-disable-next-line camelcase __webpack_nonce__ = btoa(getRequestToken()) @@ -50,3 +52,20 @@ window.addEventListener('DOMContentLoaded', function() { window.onhashchange = _.bind(OC.Util.History._onPopState, OC.Util.History) } }) + +// Fix error "CSRF check failed" +document.addEventListener('DOMContentLoaded', function() { + const form = document.getElementById('password-input-form') + if (form) { + form.addEventListener('submit', async function(event) { + event.preventDefault() + const requestToken = document.getElementById('requesttoken') + if (requestToken) { + const url = generateUrl('/csrftoken') + const resp = await Axios.get(url) + requestToken.value = resp.data.token + } + form.submit() + }) + } +}) From a42c68d519047136886960e0a7a51bcc1dbed659 Mon Sep 17 00:00:00 2001 From: Luka Trovic Date: Fri, 29 Mar 2024 09:51:38 +0100 Subject: [PATCH 3/3] feat: compile js Signed-off-by: Luka Trovic --- dist/core-main.js | 4 ++-- dist/core-main.js.map | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dist/core-main.js b/dist/core-main.js index 2a31177e87486..40936abdf81ec 100644 --- a/dist/core-main.js +++ b/dist/core-main.js @@ -1,3 +1,3 @@ /*! For license information please see core-main.js.LICENSE.txt */ -(()=>{var e,i,o,r={41548:(e,i,o)=>{"use strict";var r={};o.r(r),o.d(r,{deleteKey:()=>k,getApps:()=>v,getKeys:()=>x,getValue:()=>w,setValue:()=>y});var s={};o.r(s),o.d(s,{formatLinksPlain:()=>fi,formatLinksRich:()=>Ai,plainToRich:()=>di,richToPlain:()=>pi});var a={};o.r(a),o.d(a,{dismiss:()=>bi,query:()=>mi}),o(84315),o(7452);var c=o(61338),l=o(4523),u=o(74692),h=o.n(u),d=o(85168),p=o(96763);const A={updatableNotification:null,getDefaultNotificationFunction:null,setDefault(t){this.getDefaultNotificationFunction=t},hide(t,e){l.default.isFunction(t)&&(e=t,t=void 0),t?(t.each((function(){h()(this)[0].toastify?h()(this)[0].toastify.hideToast():p.error("cannot hide toast because object is not set"),this===this.updatableNotification&&(this.updatableNotification=null)})),e&&e.call(),this.getDefaultNotificationFunction&&this.getDefaultNotificationFunction()):p.error("Missing argument $row in OC.Notification.hide() call, caller needs to be adjusted to only dismiss its own notification")},showHtml(t,e){(e=e||{}).isHTML=!0,e.timeout=e.timeout?e.timeout:d.DH;const i=(0,d.rG)(t,e);return i.toastElement.toastify=i,h()(i.toastElement)},show(t,e){(e=e||{}).timeout=e.timeout?e.timeout:d.DH;const i=(0,d.rG)(function(t){return t.toString().split("&").join("&").split("<").join("<").split(">").join(">").split('"').join(""").split("'").join("'")}(t),e);return i.toastElement.toastify=i,h()(i.toastElement)},showUpdate(t){return this.updatableNotification&&this.updatableNotification.hideToast(),this.updatableNotification=(0,d.rG)(t,{timeout:d.DH}),this.updatableNotification.toastElement.toastify=this.updatableNotification,h()(this.updatableNotification.toastElement)},showTemporary(t,e){(e=e||{}).timeout=e.timeout||d.aR;const i=(0,d.rG)(t,e);return i.toastElement.toastify=i,h()(i.toastElement)},isHidden:()=>!h()("#content").find(".toastify").length},f=l.default.throttle((()=>{A.showTemporary(t("core","Connection to server lost"))}),7e3,{trailing:!1});let g=!1;const m={enableDynamicSlideToggle(){g=!0},showAppSidebar:function(t){(t||h()("#app-sidebar")).removeClass("disappear").show(),h()("#app-content").trigger(new(h().Event)("appresized"))},hideAppSidebar:function(t){(t||h()("#app-sidebar")).hide().addClass("disappear"),h()("#app-content").trigger(new(h().Event)("appresized"))}};var b=o(63814);function C(t,e,i){"post"!==t&&"delete"!==t||!_t.PasswordConfirmation.requiresPasswordConfirmation()?(i=i||{},h().ajax({type:t.toUpperCase(),url:(0,b.KT)("apps/provisioning_api/api/v1/config/apps")+e,data:i.data||{},success:i.success,error:i.error})):_t.PasswordConfirmation.requirePasswordConfirmation(_.bind(C,this,t,e,i))}function v(t){C("get","",t)}function x(t,e){C("get","/"+t,e)}function w(t,e,i,n){(n=n||{}).data={defaultValue:i},C("get","/"+t+"/"+e,n)}function y(t,e,i,n){(n=n||{}).data={value:i},C("post","/"+t+"/"+e,n)}function k(t,e,i){C("delete","/"+t+"/"+e,i)}const B=window.oc_appconfig||{},E={getValue:function(t,e,i,n){w(t,e,i,{success:n})},setValue:function(t,e,i){y(t,e,i)},getApps:function(t){v({success:t})},getKeys:function(t,e){x(t,{success:e})},deleteKey:function(t,e){k(t,e)}},D=void 0!==window._oc_appswebroots&&window._oc_appswebroots;var I=o(21391),S=o.n(I),T=o(78112),M=o(96763);const P={create:"POST",update:"PROPPATCH",patch:"PROPPATCH",delete:"DELETE",read:"PROPFIND"};function O(t,e){if(l.default.isArray(t))return l.default.map(t,(function(t){return O(t,e)}));var i={href:t.href};return l.default.each(t.propStat,(function(t){if("HTTP/1.1 200 OK"===t.status)for(var n in t.properties){var o=n;n in e&&(o=e[n]),i[o]=t.properties[n]}})),i.id||(i.id=z(i.href)),i}function z(t){var e=t.indexOf("?");e>0&&(t=t.substr(0,e));var i,n=t.split("/");do{i=n[n.length-1],n.pop()}while(!i&&n.length>0);return i}function R(t){return t>=200&&t<=299}function H(t,e,i,n){return t.propPatch(e.url,function(t,e){var i,n={};for(i in t){var o=e[i],r=t[i];o||(M.warn('No matching DAV property for property "'+i),o=i),(l.default.isBoolean(r)||l.default.isNumber(r))&&(r=""+r),n[o]=r}return n}(i.changed,e.davProperties),n).then((function(t){R(t.status)?l.default.isFunction(e.success)&&e.success(i.toJSON()):l.default.isFunction(e.error)&&e.error(t)}))}const N=S().noConflict();Object.assign(N,{davCall:(t,e)=>{var i=new T.dav.Client({baseUrl:t.url,xmlNamespaces:l.default.extend({"DAV:":"d","http://owncloud.org/ns":"oc"},t.xmlNamespaces||{})});i.resolveUrl=function(){return t.url};var n=l.default.extend({"X-Requested-With":"XMLHttpRequest",requesttoken:OC.requestToken},t.headers);return"PROPFIND"===t.type?function(t,e,i,n){return t.propFind(e.url,l.default.values(e.davProperties)||[],e.depth,n).then((function(t){if(R(t.status)){if(l.default.isFunction(e.success)){var i=l.default.invert(e.davProperties),n=O(t.body,i);e.depth>0&&n.shift(),e.success(n)}}else l.default.isFunction(e.error)&&e.error(t)}))}(i,t,0,n):"PROPPATCH"===t.type?H(i,t,e,n):"MKCOL"===t.type?function(t,e,i,n){return t.request(e.type,e.url,n,null).then((function(o){R(o.status)?H(t,e,i,n):l.default.isFunction(e.error)&&e.error(o)}))}(i,t,e,n):function(t,e,i,n){return n["Content-Type"]="application/json",t.request(e.type,e.url,n,e.data).then((function(t){if(R(t.status)){if(l.default.isFunction(e.success)){if("PUT"===e.type||"POST"===e.type||"MKCOL"===e.type){var n=t.body||i.toJSON(),o=t.xhr.getResponseHeader("Content-Location");return"POST"===e.type&&o&&(n.id=z(o)),void e.success(n)}if(207===t.status){var r=l.default.invert(e.davProperties);e.success(O(t.body,r))}else e.success(t.body)}}else l.default.isFunction(e.error)&&e.error(t)}))}(i,t,e,n)},davSync:(t=>(e,i,n)=>{var o={type:P[e]||e},r=i instanceof t.Collection;if("update"===e&&(i.hasInnerCollection?o.type="MKCOL":(i.usePUT||i.collection&&i.collection.usePUT)&&(o.type="PUT")),n.url||(o.url=l.default.result(i,"url")||function(){throw new Error('A "url" property or function must be specified')}()),null!=n.data||!i||"create"!==e&&"update"!==e&&"patch"!==e||(o.data=JSON.stringify(n.attrs||i.toJSON(n))),"PROPFIND"!==o.type&&(o.processData=!1),"PROPFIND"===o.type||"PROPPATCH"===o.type){var s=i.davProperties;!s&&i.model&&(s=i.model.prototype.davProperties),s&&(l.default.isFunction(s)?o.davProperties=s.call(i):o.davProperties=s),o.davProperties=l.default.extend(o.davProperties||{},n.davProperties),l.default.isUndefined(n.depth)&&(n.depth=r?1:0)}var a=n.error;n.error=function(t,e,i){n.textStatus=e,n.errorThrown=i,a&&a.call(n.context,t,e,i)};var c=n.xhr=t.davCall(l.default.extend(o,n),i);return i.trigger("request",i,c,n),c})(N)});const U=N;var j=o(71089);const L=window._oc_config||{},F=document.getElementsByTagName("head")[0].getAttribute("data-user"),W=document.getElementsByTagName("head")[0].getAttribute("data-user-displayname"),Y=void 0!==F&&F;var q=o(39285),Q=o(36882),G=o(43627);const X={YES_NO_BUTTONS:70,OK_BUTTONS:71,FILEPICKER_TYPE_CHOOSE:1,FILEPICKER_TYPE_MOVE:2,FILEPICKER_TYPE_COPY:3,FILEPICKER_TYPE_COPY_MOVE:4,FILEPICKER_TYPE_CUSTOM:5,dialogsCounter:0,alert:function(t,e,i,n){this.message(t,e,"alert",X.OK_BUTTON,i,n)},info:function(t,e,i,n){this.message(t,e,"info",X.OK_BUTTON,i,n)},confirm:function(t,e,i,n){return this.message(t,e,"notice",X.YES_NO_BUTTONS,i,n)},confirmDestructive:function(t,e,i,n,o){return this.message(t,e,"none",i,n,void 0===o||o)},confirmHtml:function(t,e,i,n){return this.message(t,e,"notice",X.YES_NO_BUTTONS,i,n,!0)},prompt:function(e,i,n,o,r,s){return h().when(this._getMessageTemplate()).then((function(a){var c="oc-dialog-"+X.dialogsCounter+"-content",u="#"+c,d=a.octemplate({dialog_name:c,title:i,message:e,type:"notice"}),p=h()("");p.attr("type",s?"password":"text").attr("id",c+"-input").attr("placeholder",r);var A=h()("