Merge pull request #18778 from nextcloud/fix/fetch-request-token-offline-online

Fetch a new request token as soon as the browser becomes online
pull/19338/head
Roeland Jago Douma 2020-02-06 21:28:08 +07:00 committed by GitHub
commit 368b401ff5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 129 additions and 57 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -20,6 +20,7 @@
*/
import $ from 'jquery'
import { emit } from '@nextcloud/event-bus'
import { generateUrl } from './OC/routing'
import OC from './OC'
@ -54,6 +55,34 @@ const getInterval = () => {
)
}
const getToken = async() => {
const url = generateUrl('/csrftoken')
// Not using Axios here as Axios is not stubbable with the sinon fake server
// see https://stackoverflow.com/questions/41516044/sinon-mocha-test-with-async-ajax-calls-didnt-return-promises
// see js/tests/specs/coreSpec.js for the tests
const resp = await $.get(url)
return resp.token
}
const poll = async() => {
try {
const token = await getToken()
setRequestToken(token)
} catch (e) {
console.error('session heartbeat failed', e)
}
}
const startPolling = () => {
const interval = setInterval(poll, getInterval() * 1000)
console.info('session heartbeat polling started')
return interval
}
/**
* Calls the server periodically to ensure that session and CSRF
* token doesn't expire
@ -63,12 +92,35 @@ export const initSessionHeartBeat = () => {
console.info('session heartbeat disabled')
return
}
let interval = startPolling()
window.addEventListener('online', async() => {
console.info('browser is online again, resuming heartbeat')
interval = startPolling()
try {
await poll()
console.info('session token successfully updated after resuming network')
setInterval(() => {
$.ajax(generateUrl('/csrftoken'))
.then(resp => setRequestToken(resp.token))
.fail(e => {
console.error('session heartbeat failed', e)
// Let apps know we're online and requests will have the new token
emit('networkOnline', {
success: true
})
}, getInterval() * 1000)
} catch (e) {
console.error('could not update session token after resuming network', e)
// Let apps know we're online but requests might have an outdated token
emit('networkOnline', {
success: false
})
}
})
window.addEventListener('offline', () => {
console.info('browser is offline, stopping heartbeat')
// Let apps know we're offline
emit('networkOffline', {})
clearInterval(interval)
console.info('session heartbeat polling stopped')
})
}