Browse Source

refactor: move axios interceptor to nuxt plugin

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/2716/head
Pranav C 2 years ago
parent
commit
19d38201e2
  1. 101
      packages/nc-gui-v2/composables/user.ts
  2. 39
      packages/nc-gui-v2/package-lock.json
  3. 99
      packages/nc-gui-v2/plugins/api.ts

101
packages/nc-gui-v2/composables/user.ts

@ -1,18 +1,16 @@
import { store } from 'nuxt3-store'
import { useNuxtApp } from '#app'
export const useUser = () => {
const user = store({
name: 'user',
type: 'localstorage',
value: { token: null, user: null },
reactiveType: 'reactive',
version: '1.0.0',
})
const user = store({
name: 'user',
type: 'localstorage',
value: { token: null, user: null },
reactiveType: 'reactive',
version: '1.0.0',
})
export const useUser = () => {
const { $api } = useNuxtApp()
const route = useRoute()
const router = useRouter()
const getUser = async (args = {}) => {
const userInfo = await $api.auth.me(args, {
@ -28,88 +26,5 @@ export const useUser = () => {
user.token = token
}
$api?.instance?.interceptors.request.use((config) => {
config.headers['xc-gui'] = 'true'
if (user?.token)
config.headers['xc-auth'] = user?.token
if (!config.url.endsWith('/user/me') && !config.url.endsWith('/admin/roles')) {
// config.headers['xc-preview'] = store.state.users.previewAs
}
if (!config.url.endsWith('/user/me') && !config.url.endsWith('/admin/roles')) {
if (route && route.params && route.params.shared_base_id)
config.headers['xc-shared-base-id'] = route.params.shared_base_id
}
return config
})
// $axios.setBaseURL('http://localhost:8080')
$api?.instance?.interceptors.response.use((response) => {
// Return a successful response back to the calling service
return response
}, (error) => {
if (error.response && error.response.data && error.response.data.msg === 'Database config not found') {
router.replace('/project/0')
return
}
// Return any error which is not due to authentication back to the calling service
if (!error.response || error.response.status !== 401) {
return new Promise((resolve, reject) => {
reject(error)
})
}
// Logout user if token refresh didn't work or user is disabled
if (error.config.url === '/auth/refresh-token') {
// todo: clear token
// store.dispatch('users/ActSignOut')
setToken(null)
return new Promise((resolve, reject) => {
reject(error)
})
}
// Try request again with new token
return $api.instance.post('/auth/refresh-token', null, {
withCredentials: true,
})
.then((token) => {
// New request with new token
const config = error.config
config.headers['xc-auth'] = token.data.token
user.token = token.data.token
return new Promise((resolve, reject) => {
$api.instance.request(config).then((response) => {
resolve(response)
}).catch((error) => {
reject(error)
})
})
})
.catch(async (error) => {
// todo: clear token
// await store.dispatch('users/ActSignOut')
setToken(null)
if (store.state.project.appInfo.firstUser) {
router.replace('/')
}
else {
// $toast.clear()
// $toast.info('Token Expired. Please login again.', {
// position: 'bottom-center'
// }).goAway(5000)
router.replace('/user/authentication/signin')
}
return Promise.reject(error)
})
})
return { user, setToken, getUser }
}

39
packages/nc-gui-v2/package-lock.json generated

@ -10,7 +10,7 @@
"primeflex": "3.2.0",
"primeicons": "5.0.0",
"primevue": "3.10.0",
"vuetify": "^3.0.0-alpha.12"
"vuetify": "^3.0.0-alpha.13"
},
"devDependencies": {
"@antfu/eslint-config": "^0.25.2",
@ -22,7 +22,7 @@
}
},
"../nocodb-sdk": {
"version": "0.92.0",
"version": "0.92.3",
"license": "MIT",
"dependencies": {
"axios": "^0.21.1",
@ -11556,15 +11556,36 @@
"integrity": "sha512-UBc1Pg1T3yZ97vsA2ueER0F6GbJebLHYlEi4ou1H5YL4KWvMOOWwpYo9/QpWq93wxKG6Wo13IY74Hcn/f7c7Bg=="
},
"node_modules/vuetify": {
"version": "3.0.0-alpha.12",
"resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.0.0-alpha.12.tgz",
"integrity": "sha512-F9TwV3Xk6J/bSH422kATrKeIiumGRkzGJPsvM0/8vPwYF0HWh7dHRhhYsIKkfhl5UJl/LYdeGNm1L8+jtldA0w==",
"version": "3.0.0-beta.5",
"resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.0.0-beta.5.tgz",
"integrity": "sha512-mU+pO5ZAZOR2Z7eVBoPwZw6nePxT5Sdqpsa4++Q99TwVxXQ7jl76Cy97v72MkDYWfxjDjj8XvW6IqNPGrJpU8w==",
"engines": {
"node": "^12.20 || >=14.13"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/johnleider"
},
"peerDependencies": {
"vue": "^3.2.19"
"@formatjs/intl": "^1.0.0 || ^2.0.0",
"vite-plugin-vuetify": "1.0.0-alpha.12",
"vue": "^3.2.0",
"vue-i18n": "^9.0.0",
"webpack-plugin-vuetify": "2.0.0-alpha.11"
},
"peerDependenciesMeta": {
"@formatjs/intl": {
"optional": true
},
"vite-plugin-vuetify": {
"optional": true
},
"vue-i18n": {
"optional": true
},
"webpack-plugin-vuetify": {
"optional": true
}
}
},
"node_modules/watchpack": {
@ -20369,9 +20390,9 @@
}
},
"vuetify": {
"version": "3.0.0-alpha.12",
"resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.0.0-alpha.12.tgz",
"integrity": "sha512-F9TwV3Xk6J/bSH422kATrKeIiumGRkzGJPsvM0/8vPwYF0HWh7dHRhhYsIKkfhl5UJl/LYdeGNm1L8+jtldA0w==",
"version": "3.0.0-beta.5",
"resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.0.0-beta.5.tgz",
"integrity": "sha512-mU+pO5ZAZOR2Z7eVBoPwZw6nePxT5Sdqpsa4++Q99TwVxXQ7jl76Cy97v72MkDYWfxjDjj8XvW6IqNPGrJpU8w==",
"requires": {}
},
"watchpack": {

99
packages/nc-gui-v2/plugins/api.ts

@ -1,9 +1,108 @@
import { Api } from 'nocodb-sdk'
import { defineNuxtPlugin } from 'nuxt3/app'
const addAxiosInterceptors = ($api: Api<any>) => {
const router = useRouter()
const route = useRoute()
const { user, setToken } = useUser()
$api?.instance?.interceptors.request.use((config) => {
config.headers['xc-gui'] = 'true'
if (user?.token)
config.headers['xc-auth'] = user?.token
if (!config.url.endsWith('/user/me') && !config.url.endsWith('/admin/roles')) {
// config.headers['xc-preview'] = store.state.users.previewAs
}
if (!config.url.endsWith('/user/me') && !config.url.endsWith('/admin/roles')) {
if (route && route.params && route.params.shared_base_id)
config.headers['xc-shared-base-id'] = route.params.shared_base_id
}
return config
})
// $axios.setBaseURL('http://localhost:8080')
$api?.instance?.interceptors.response.use((response) => {
// Return a successful response back to the calling service
return response
}, (error) => {
if (error.response && error.response.data && error.response.data.msg === 'Database config not found') {
router.replace('/project/0')
return
}
// Return any error which is not due to authentication back to the calling service
if (!error.response || error.response.status !== 401) {
return new Promise((resolve, reject) => {
reject(error)
})
}
// Logout user if token refresh didn't work or user is disabled
if (error.config.url === '/auth/refresh-token') {
// todo: clear token
// store.dispatch('users/ActSignOut')
setToken(null)
return new Promise((resolve, reject) => {
reject(error)
})
}
// Try request again with new token
return $api.instance.post('/auth/refresh-token', null, {
withCredentials: true,
})
.then((token) => {
// New request with new token
const config = error.config
config.headers['xc-auth'] = token.data.token
user.token = token.data.token
return new Promise((resolve, reject) => {
$api.instance.request(config).then((response) => {
resolve(response)
}).catch((error) => {
reject(error)
})
})
})
.catch(async (error) => {
// todo: clear token
// await store.dispatch('users/ActSignOut')
setToken(null)
// todo: handle new user
// if (store.state.project.appInfo.firstUser) {
// router.replace('/')
// }
// else {
// $toast.clear()
// $toast.info('Token Expired. Please login again.', {
// position: 'bottom-center'
// }).goAway(5000)
router.replace('/user/authentication/signin')
// }
return Promise.reject(error)
})
})
}
export default defineNuxtPlugin((nuxtApp) => {
const { user } = useUser()
const api = getApi(null, null)
watch(() => user.token, (newToken, oldToken) => {
if (newToken !== oldToken)
addAxiosInterceptors(api)
})
addAxiosInterceptors(api)
nuxtApp.provide('api', api)
})

Loading…
Cancel
Save