Browse Source

Merge pull request #5066 from nocodb/fix/3792-refresh-token-logging-out

fix: Refresh token based token generation not working
pull/5076/head
աɨռɢӄաօռɢ 2 years ago committed by GitHub
parent
commit
9f153d299e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      packages/nc-gui/components.d.ts
  2. 1
      packages/nc-gui/composables/useApi/interceptors.ts
  3. 29
      packages/nc-gui/composables/useGlobal/actions.ts
  4. 2
      packages/nc-gui/composables/useGlobal/index.ts
  5. 6
      packages/nc-gui/middleware/auth.global.ts
  6. 12
      packages/nocodb/src/lib/meta/api/userApi/userApis.ts

1
packages/nc-gui/components.d.ts vendored

@ -81,7 +81,6 @@ declare module '@vue/runtime-core' {
ClaritySuccessLine: typeof import('~icons/clarity/success-line')['default'] ClaritySuccessLine: typeof import('~icons/clarity/success-line')['default']
EvaEmailOutline: typeof import('~icons/eva/email-outline')['default'] EvaEmailOutline: typeof import('~icons/eva/email-outline')['default']
IcBaselineMoreVert: typeof import('~icons/ic/baseline-more-vert')['default'] IcBaselineMoreVert: typeof import('~icons/ic/baseline-more-vert')['default']
Icon: typeof import('~icons/ic/on')['default']
IcOutlineInsertDriveFile: typeof import('~icons/ic/outline-insert-drive-file')['default'] IcOutlineInsertDriveFile: typeof import('~icons/ic/outline-insert-drive-file')['default']
IcRoundEdit: typeof import('~icons/ic/round-edit')['default'] IcRoundEdit: typeof import('~icons/ic/round-edit')['default']
IcRoundKeyboardArrowDown: typeof import('~icons/ic/round-keyboard-arrow-down')['default'] IcRoundKeyboardArrowDown: typeof import('~icons/ic/round-keyboard-arrow-down')['default']

1
packages/nc-gui/composables/useApi/interceptors.ts

@ -40,7 +40,6 @@ export function addAxiosInterceptors(api: Api<any>) {
// Logout user if token refresh didn't work or user is disabled // Logout user if token refresh didn't work or user is disabled
if (error.config.url === '/auth/token/refresh') { if (error.config.url === '/auth/token/refresh') {
state.signOut() state.signOut()
return Promise.reject(error) return Promise.reject(error)
} }

29
packages/nc-gui/composables/useGlobal/actions.ts

@ -28,19 +28,22 @@ export function useGlobalActions(state: State): Actions {
const nuxtApp = useNuxtApp() const nuxtApp = useNuxtApp()
const t = nuxtApp.vueApp.i18n.global.t const t = nuxtApp.vueApp.i18n.global.t
nuxtApp.$api.instance return new Promise((resolve) => {
.post('/auth/token/refresh', null, { nuxtApp.$api.instance
withCredentials: true, .post('/auth/token/refresh', null, {
}) withCredentials: true,
.then((response) => { })
if (response.data?.token) { .then((response) => {
signIn(response.data.token) if (response.data?.token) {
} signIn(response.data.token)
}) }
.catch((err) => { })
message.error(err.message || t('msg.error.youHaveBeenSignedOut')) .catch((err) => {
signOut() message.error(err.message || t('msg.error.youHaveBeenSignedOut'))
}) signOut()
})
.finally(resolve)
})
} }
const loadAppInfo = async () => { const loadAppInfo = async () => {

2
packages/nc-gui/composables/useGlobal/index.ts

@ -53,7 +53,7 @@ export const useGlobal = createGlobalState((): UseGlobalReturn => {
state.jwtPayload.value.exp && state.jwtPayload.value.exp &&
state.jwtPayload.value.exp - 5 * 60 < state.timestamp.value / 1000 state.jwtPayload.value.exp - 5 * 60 < state.timestamp.value / 1000
), ),
async (expiring) => { async (expiring: boolean) => {
if (getters.signedIn.value && state.jwtPayload.value && expiring) { if (getters.signedIn.value && state.jwtPayload.value && expiring) {
await actions.refreshToken() await actions.refreshToken()
} }

6
packages/nc-gui/middleware/auth.global.ts

@ -52,7 +52,11 @@ export default defineNuxtRouteMiddleware(async (to, from) => {
return navigateTo('/signup') return navigateTo('/signup')
} }
return navigateTo('/signin') /** try generating access token using refresh token */
await state.refreshToken()
/** if user is still not signed in, redirect to signin page */
if (!state.signedIn.value) return navigateTo('/signin')
} else if (to.meta.requiresAuth === false && state.signedIn.value) { } else if (to.meta.requiresAuth === false && state.signedIn.value) {
/** /**
* if user was turned away from non-auth page but also came from a non-auth page (e.g. user went to /signin and reloaded the page) * if user was turned away from non-auth page but also came from a non-auth page (e.g. user went to /signin and reloaded the page)

12
packages/nocodb/src/lib/meta/api/userApi/userApis.ts

@ -534,7 +534,7 @@ const mapRoutes = (router) => {
'/user/password/change', '/user/password/change',
ncMetaAclMw(passwordChange, 'passwordChange') ncMetaAclMw(passwordChange, 'passwordChange')
); );
router.post('/auth/token/refresh', ncMetaAclMw(refreshToken, 'refreshToken')); router.post('/auth/token/refresh', catchError(refreshToken));
/* Google auth apis */ /* Google auth apis */
@ -573,10 +573,7 @@ const mapRoutes = (router) => {
'/api/v1/db/auth/password/change', '/api/v1/db/auth/password/change',
ncMetaAclMw(passwordChange, 'passwordChange') ncMetaAclMw(passwordChange, 'passwordChange')
); );
router.post( router.post('/api/v1/db/auth/token/refresh', catchError(refreshToken));
'/api/v1/db/auth/token/refresh',
ncMetaAclMw(refreshToken, 'refreshToken')
);
router.get( router.get(
'/api/v1/db/auth/password/reset/:tokenId', '/api/v1/db/auth/password/reset/:tokenId',
catchError(renderPasswordReset) catchError(renderPasswordReset)
@ -607,10 +604,7 @@ const mapRoutes = (router) => {
'/api/v1/auth/password/change', '/api/v1/auth/password/change',
ncMetaAclMw(passwordChange, 'passwordChange') ncMetaAclMw(passwordChange, 'passwordChange')
); );
router.post( router.post('/api/v1/auth/token/refresh', catchError(refreshToken));
'/api/v1/auth/token/refresh',
ncMetaAclMw(refreshToken, 'refreshToken')
);
// respond with password reset page // respond with password reset page
router.get('/auth/password/reset/:tokenId', catchError(renderPasswordReset)); router.get('/auth/password/reset/:tokenId', catchError(renderPasswordReset));
}; };

Loading…
Cancel
Save