Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions frontend/src/components/navbar/Navbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -965,7 +965,7 @@
this.selectedItems = []
this.selectAll = false
} else {
ElMessage.warning(error.value.msg)
ElMessage.warning(error.value?.msg)
}
},
async allClear() {
Expand All @@ -992,7 +992,7 @@
this.selectedItems = []
this.selectAll = false
} else {
ElMessage.warning(error.value.msg)
ElMessage.warning(error.value?.msg)
}
},
handleLocaleChange(locale) {
Expand All @@ -1005,7 +1005,6 @@
if (data.value) {
this.userStore.initialize(data.value.data)
} else {
console.log(error.value.msg)
this.clearCookies()
}
},
Expand Down Expand Up @@ -1077,7 +1076,7 @@
if (data.value) {
ElMessage.success(this.$t('navbar.settingsSuccess'))
} else {
ElMessage.warning(error.value.msg)
ElMessage.warning(error.value?.msg)
}
},
async subForm() {
Expand Down Expand Up @@ -1105,7 +1104,7 @@
ElMessage.success(this.$t('navbar.settingsSuccess'))
this.showUserSet = false
} else {
ElMessage.warning(error.value.msg)
ElMessage.warning(error.value?.msg)
}
} catch (error) {
console.log('表单验证失败:', error)
Expand All @@ -1127,7 +1126,7 @@
this.msgList[index].is_read = true
this.getMsgNum()
} else {
ElMessage.warning(error.value.msg)
ElMessage.warning(error.value?.msg)
}
},
async getMsgNum() {
Expand Down
39 changes: 39 additions & 0 deletions frontend/src/packs/authDialog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { useCookies } from 'vue3-cookies'
import { ElMessageBox } from 'element-plus'
import { user_sessions as sessions_en } from '../locales/en_js/user_sessions.js'
import { user_sessions as sessions_zh } from '../locales/zh_js/user_sessions.js'
import { logout } from './auth'
import { dialogState } from './dialogState'

const { cookies } = useCookies()

export const popupReloginDialog = () => {
if (dialogState.isReloginDialogShowing) {
return
}

dialogState.isReloginDialogShowing = true

const currentURL = window.location.pathname + window.location.search + window.location.hash;
cookies.set('previous_path', currentURL, '7d', '/', '', false, false);

const sessionLocale = cookies.get('locale') === 'en' ? sessions_en : sessions_zh

ElMessageBox.confirm(sessionLocale.expiredDesc, sessionLocale.expiredTitle, {
showClose: true,
closeOnClickModal: true,
closeOnPressEscape: true,
confirmButtonText: sessionLocale.reLogin,
cancelButtonText: sessionLocale.cancel
}).then(() => {
const previousPath = cookies.get('previous_path')
logout()
cookies.set('previous_path', previousPath, '7d', '/', '', false, false)
window.location.href = '/login'
}).catch(() => {
logout()
window.location.href = '/logout'
}).finally(() => {
dialogState.isReloginDialogShowing = false
})
}
4 changes: 4 additions & 0 deletions frontend/src/packs/dialogState.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// 全局共享的对话框状态,防止重复弹出登录对话框
export const dialogState = {
isReloginDialogShowing: false
}
2 changes: 2 additions & 0 deletions frontend/src/packs/jwtFetch.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ const { cookies } = useCookies();
const jwtFetch = (url, options = {}, forceLogin = false) => {
const jwtToken = cookies.get('user_token')
if (forceLogin && !jwtToken) {
const fullPath = window.location.pathname + window.location.search + window.location.hash;
cookies.set('previous_path', fullPath, '7d', '/', '', false, false);
window.location.href = "/login"
}
options.headers = options.headers || {}
Expand Down
38 changes: 27 additions & 11 deletions frontend/src/packs/refreshJWT.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useCookies } from "vue3-cookies";
import { jwtDecode } from "jwt-decode";
import { popupReloginDialog } from './authDialog'

const { cookies } = useCookies()

Expand All @@ -10,20 +11,35 @@ const refreshJWT = async () => {

if(loginIdentity) {
if (jwt) {
const jwtInfos = jwtDecode(jwt);
const expireTime = jwtInfos.exp;
if (currentTime >= expireTime) {
await fetch('/internal_api/users/jwt_token', {method: 'PUT'})
} else {
// if user token will expire soon, refresh
// if user token will not expire soon, do nothing
const differenceInMinutes = Math.floor((expireTime - currentTime) / (60));
if (differenceInMinutes < 120) {
await fetch('/internal_api/users/jwt_token', {method: 'PUT'})
try {
const jwtInfos = jwtDecode(jwt);
const expireTime = jwtInfos.exp;
if (currentTime >= expireTime) {
const response = await fetch('/internal_api/users/jwt_token', {method: 'PUT'})
if (!response.ok) {
throw new Error('Token refresh failed')
}
} else {
const differenceInMinutes = Math.floor((expireTime - currentTime) / (60));
if (differenceInMinutes < 120) {
const response = await fetch('/internal_api/users/jwt_token', {method: 'PUT'})
if (!response.ok) {
throw new Error('Token refresh failed')
}
}
}
} catch (error) {
popupReloginDialog()
}
} else {
await fetch('/internal_api/users/jwt_token', {method: 'PUT'})
try {
const response = await fetch('/internal_api/users/jwt_token', {method: 'PUT'})
if (!response.ok) {
throw new Error('Token refresh failed')
}
} catch (error) {
popupReloginDialog()
}
}
}
}
Expand Down
19 changes: 17 additions & 2 deletions frontend/src/packs/useFetchApi.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,21 @@ import { user_sessions as sessions_en } from '../locales/en_js/user_sessions.js'
import { user_sessions as sessions_zh } from '../locales/zh_js/user_sessions.js'

import { logout } from './auth'
import { getDefaultLanguage } from './utils'
import { dialogState } from './dialogState'

const { cookies } = useCookies()

const popupReloginDialog = () => {
if (dialogState.isReloginDialogShowing) {
return
}

dialogState.isReloginDialogShowing = true

const currentURL = window.location.pathname + window.location.search;
cookies.set('previous_path', currentURL, '7d', '/', '', false, false);

const sessionLocale =
cookies.get('locale') === 'en' ? sessions_en : sessions_zh
ElMessageBox.confirm(sessionLocale.expiredDesc, sessionLocale.expiredTitle, {
Expand All @@ -19,13 +30,17 @@ const popupReloginDialog = () => {
'cancelButtonText': sessionLocale.cancelLogin
})
.then(() => {
window.location.href = '/logout?redirect_to=/login'
const previousPath = cookies.get('previous_path')
logout()
cookies.set('previous_path', previousPath, '7d', '/', '', false, false)
window.location.href = '/login'
})
.catch(() => {
logout()
window.location.href = '/logout'
})
.finally(() => {
logout()
dialogState.isReloginDialogShowing = false
})
}

Expand Down
3 changes: 2 additions & 1 deletion frontend/src/packs/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ export const beiJingTimeParser = (utcTimeStr) => {
}

export const ToLoginPage = () => {
cookies.set('previous_path', window.location.pathname)
const currentURL = window.location.pathname + window.location.search + window.location.hash;
cookies.set('previous_path', currentURL, '7d', '/', '', false, false);
window.location.href = '/login'
}

Expand Down
1 change: 1 addition & 0 deletions internal/handlers/render/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ func (i *SessionHandlerImpl) Create(ctx *gin.Context) {

previousPath, _ := ctx.Cookie("previous_path")
if previousPath != "" {
ctx.SetCookie("previous_path", "", -1, "/", "", false, false)
ctx.Redirect(http.StatusFound, previousPath)
} else {
ctx.Redirect(http.StatusFound, "/")
Expand Down
7 changes: 5 additions & 2 deletions internal/middleware/auth_middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,11 @@ func (a *MiddlewareImpl) CheckCurrentUser() gin.HandlerFunc {
return func(ctx *gin.Context) {
currentUser := a.jwtUtils.GetCurrentUser(ctx)
if currentUser == nil {
currentPath := ctx.Request.URL.Path
ctx.SetCookie("previous_path", currentPath, 3600*24*7, "/", "", false, false)
fullURL := ctx.Request.URL.Path
if ctx.Request.URL.RawQuery != "" {
fullURL = fullURL + "?" + ctx.Request.URL.RawQuery
}
ctx.SetCookie("previous_path", fullURL, 3600*24*7, "/", "", false, false)
ctx.Redirect(http.StatusFound, "/login")
ctx.Abort()
return
Expand Down