1
0
mirror of https://gitlab.com/bramw/baserow.git synced 2024-11-21 23:37:55 +00:00
bramw_baserow/web-frontend/modules/core/utils/auth.js
2024-06-24 21:30:23 +00:00

123 lines
3.8 KiB
JavaScript

import { isSecureURL } from '@baserow/modules/core/utils/string'
import jwtDecode from 'jwt-decode'
import { getDomain } from 'tldjs'
const cookieTokenName = 'jwt_token'
export const userSourceCookieTokenName = 'user_source_token'
export const userSessionCookieName = 'user_session'
const refreshTokenMaxAge = 60 * 60 * 24 * 7
export const setToken = (
{ $config, $cookies },
token,
key = cookieTokenName,
configuration = { sameSite: null }
) => {
if (process.SERVER_BUILD) return
const secure = isSecureURL($config.PUBLIC_WEB_FRONTEND_URL)
$cookies.set(key, token, {
path: '/',
maxAge: refreshTokenMaxAge,
sameSite:
configuration.sameSite || $config.BASEROW_FRONTEND_SAME_SITE_COOKIE,
secure,
})
}
/**
* Sets a session cookie in the browser to store the user's signed session payload upon
* login. This cookie facilitates backend authentication for GET requests, such as
* downloading files with the secure_file_serve feature, when the Authorization header
* is unavailable. The payload includes a token hash to invalidate the cookie upon
* logout.
*
* @param {*} app: the nuxt app instance
* @param {*} signedUserSession: the signed user session payload to be stored in the
* cookie
* @param {*} key: the cookie name
* @param {*} configuration: the configuration object with the sameSite key
* @returns
*/
export const setUserSessionCookie = (
{ $config, $cookies },
signedUserSession,
key = userSessionCookieName,
configuration = { sameSite: null }
) => {
if (process.SERVER_BUILD) return
const secure = isSecureURL($config.PUBLIC_WEB_FRONTEND_URL)
// To make the cookie available to all subdomains, set the domain to the top-level
// domain. This is necessary for the secure_file_serve feature to work across
// subdomains, as when the backend serves files from a different subdomain from the
// frontend. The top-level domain is extracted from the backend URL.
// NOTE: For security reasons, it's not possible to set a cookie for a different
// domain, so this won't work if the frontend and backend are on different domains.
const topLevelDomain = getDomain($config.PUBLIC_BACKEND_URL)
$cookies.set(key, signedUserSession, {
path: '/',
maxAge: refreshTokenMaxAge,
sameSite:
configuration.sameSite || $config.BASEROW_FRONTEND_SAME_SITE_COOKIE,
secure,
domain: topLevelDomain,
})
}
export const unsetToken = ({ $cookies }, key = cookieTokenName) => {
if (process.SERVER_BUILD) return
$cookies.remove(key)
}
export const unsetUserSessionCookie = (
{ $cookies },
key = userSessionCookieName
) => {
if (process.SERVER_BUILD) return
$cookies.remove(key)
}
export const getToken = ({ $cookies }, key = cookieTokenName) => {
return $cookies.get(key)
}
export const getTokenIfEnoughTimeLeft = (
{ $cookies },
key = cookieTokenName
) => {
const token = getToken({ $cookies }, key)
const now = Math.ceil(new Date().getTime() / 1000)
let data
try {
data = jwtDecode(token)
} catch (error) {
return null
}
// Return the token if it is still valid for more of the 10% of the lifespan.
return data && (data.exp - now) / (data.exp - data.iat) > 0.1 ? token : null
}
export const logoutAndRedirectToLogin = (
router,
store,
showSessionExpiredToast = false,
showPasswordChangedToast = false,
invalidateToken = false
) => {
if (showPasswordChangedToast) {
store.dispatch('auth/forceLogoff')
} else {
store.dispatch('auth/logoff', { invalidateToken })
}
router.push({ name: 'login', query: { noredirect: null } }, () => {
if (showSessionExpiredToast) {
store.dispatch('toast/setUserSessionExpired', true)
} else if (showPasswordChangedToast) {
store.dispatch('toast/setUserPasswordChanged', true)
}
store.dispatch('auth/clearAllStoreUserData')
})
}