Skip to content

Commit 1d1cb05

Browse files
committed
fix: Redirect user to login if session is terminated
If a session timed out or was closed in another tab, then currently the user gets random error messages. This intercepts 401 responses (should only happen if logged out, or the users does something wrong). If we get a 401, we make sure its because of the session, by checking if the user can access the files app. If that is also the case we forward the user to the login page and set the redirect URL to the last used URL. Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
1 parent 7c67df6 commit 1d1cb05

1 file changed

Lines changed: 48 additions & 4 deletions

File tree

core/src/utils/xhr-request.js

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
* SPDX-License-Identifier: AGPL-3.0-or-later
44
*/
55

6-
import { getRootUrl } from '@nextcloud/router'
6+
import { getCurrentUser } from '@nextcloud/auth'
7+
import { generateUrl, getRootUrl } from '@nextcloud/router'
78

89
/**
910
*
@@ -26,6 +27,45 @@ const isNextcloudUrl = (url) => {
2627
|| (isRelativeUrl(url) && url.startsWith(getRootUrl()))
2728
}
2829

30+
31+
/**
32+
* Check if a user was logged in but is now logged-out.
33+
* If this is the case then the user will be forwarded to the login page.
34+
* @returns {Promise<void>}
35+
*/
36+
async function checkLoginStatus() {
37+
// skip if no logged in user
38+
if (getCurrentUser() === null) {
39+
return
40+
}
41+
42+
// skip if already running
43+
if (checkLoginStatus.running === true) {
44+
return
45+
}
46+
47+
// only run one request in parallel
48+
checkLoginStatus.running = true
49+
50+
try {
51+
// We need to check this as a 401 in the first place could also come from other reasons
52+
const { status } = await window.fetch(generateUrl('/apps/files'))
53+
if (status === 401) {
54+
console.warn('User session was terminated, forwarding to login page.')
55+
window.location = generateUrl(
56+
'/login?redirect_url={redirect}',
57+
{
58+
redirect: window.location.pathname + window.location.search,
59+
},
60+
)
61+
}
62+
} catch (error) {
63+
console.warn('Could not check login-state')
64+
} finally {
65+
delete checkLoginStatus.running
66+
}
67+
}
68+
2969
/**
3070
* Intercept XMLHttpRequest and fetch API calls to add X-Requested-With header
3171
*
@@ -42,10 +82,10 @@ export const interceptRequests = () => {
4282
})(XMLHttpRequest.prototype.open)
4383

4484
window.fetch = (function(fetch) {
45-
return (resource, options) => {
85+
return async (resource, options) => {
4686
// fetch allows the `input` to be either a Request object or any stringifyable value
4787
if (!isNextcloudUrl(resource.url ?? resource.toString())) {
48-
return fetch(resource, options)
88+
return await fetch(resource, options)
4989
}
5090
if (!options) {
5191
options = {}
@@ -60,7 +100,11 @@ export const interceptRequests = () => {
60100
options.headers['X-Requested-With'] = 'XMLHttpRequest'
61101
}
62102

63-
return fetch(resource, options)
103+
const response = await fetch(resource, options)
104+
if (response.status === 401) {
105+
checkLoginStatus()
106+
}
107+
return response
64108
}
65109
})(window.fetch)
66110
}

0 commit comments

Comments
 (0)