Skip to content

Commit

Permalink
Merge pull request #3390 from nextcloud/backport/3224/stable27
Browse files Browse the repository at this point in the history
[stable27] fix: Disable auto logout while editing
  • Loading branch information
juliushaertl committed Jan 3, 2024
2 parents fe50e23 + 27943dd commit 14edf32
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 1 deletion.
1 change: 1 addition & 0 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
['name' => 'document#createFromTemplate', 'url' => 'indexTemplate', 'verb' => 'GET'],
['name' => 'document#publicPage', 'url' => '/public', 'verb' => 'GET'],
['name' => 'document#token', 'url' => '/token', 'verb' => 'POST'],
['name' => 'document#heartbeat', 'url' => '/heartbeat', 'verb' => 'GET'],

['name' => 'document#editOnline', 'url' => 'editonline', 'verb' => 'GET'],
['name' => 'document#editOnlineTarget', 'url' => 'editonline/{fileId}/{target}', 'verb' => 'GET'],
Expand Down
8 changes: 8 additions & 0 deletions lib/Controller/DocumentController.php
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,14 @@ public function token(int $fileId, ?string $shareToken = null, ?string $path = n
}
}

/**
* Since collabora does not extend the session on interaction we need to manually trigger this while editing
*/
#[NoAdminRequired]
public function heartbeat(): DataResponse {
return new DataResponse();
}

/**
* @throws NotPermittedException
* @throws NotFoundException
Expand Down
101 changes: 101 additions & 0 deletions src/mixins/autoLogout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* @copyright Copyright (c) 2023 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import axios from '@nextcloud/axios'
import { loadState } from '@nextcloud/initial-state'
import { generateUrl } from '@nextcloud/router'
import { getCurrentUser } from '@nextcloud/auth'

const config = loadState('core', 'config', {})

const getInterval = () => {
const interval = config.session_lifetime ? Math.floor(config.session_lifetime / 2) : 900
return Math.min(24 * 3600, Math.max(60, interval))
}

export default {

data() {
return {
autoLogoutInterval: null,
autoLogoutRegistered: false,
}
},

mounted() {
if (!getCurrentUser()) {
return
}

if (config?.auto_logout || !config?.session_keepalive) {
this.autoLogoutInterval = setInterval(this.registerCheck, 10000)
}
},

beforeDestroy() {
if (this.autoLogoutInterval) {
clearInterval(this.autoLogoutInterval)
}
},

methods: {
extendAutoLogout() {
const oldValue = localStorage.getItem('lastActive')
const newValue = Date.now().toString()
localStorage.setItem('lastActive', newValue)
const event = new StorageEvent('storage', {
key: 'lastActive',
oldValue,
newValue,
})
window.dispatchEvent(event)
},
registerCheck() {
if (!this.autoLogoutRegistered && this.postMessage) {
this.postMessage.registerPostMessageHandler(this.handleGetUserStateResponse)
this.autoLogoutRegistered = true
}
if (this.autoLogoutRegistered && this.postMessage) {
this.sendPostMessage('Get_User_State')
}
},
handleGetUserStateResponse({ parsed: { msgId, args } }) {
if (msgId !== 'Get_User_State_Resp') {
return
}

const elapsed = args.Elapsed
const lastActive = Number(localStorage.getItem('lastActive'))
const timeSinceLastActive = Date.now() - lastActive
const recheckAfter = (getInterval() * 1000)

if (!config.session_keepalive && timeSinceLastActive > recheckAfter) {
axios.get(generateUrl('/apps/richdocuments/heartbeat'))
}

if (elapsed < 30) {
console.debug('[richdocuments] Extending auto logout timeout, office idle since ' + elapsed, timeSinceLastActive, recheckAfter, timeSinceLastActive > recheckAfter)
this.extendAutoLogout()
}
},
},

}
3 changes: 2 additions & 1 deletion src/view/Office.vue
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ import {
getUIDefaults,
} from '../helpers/coolParameters.js'
import Config from '../services/config.tsx'
import autoLogout from '../mixins/autoLogout.js'
import openLocal from '../mixins/openLocal.js'
import pickLink from '../mixins/pickLink.js'
import saveAs from '../mixins/saveAs.js'
Expand All @@ -124,7 +125,7 @@ export default {
ZoteroHint,
},
mixins: [
openLocal, pickLink, saveAs, uiMention, version,
autoLogout, openLocal, pickLink, saveAs, uiMention, version,
],
props: {
filename: {
Expand Down

0 comments on commit 14edf32

Please sign in to comment.