diff --git a/cmd/webserver.go b/cmd/webserver.go
index 1445d349..feb8e8e4 100644
--- a/cmd/webserver.go
+++ b/cmd/webserver.go
@@ -153,15 +153,6 @@ func startWebServer(c *cli.Context) error {
apiRoute.POST("/register.json", bindApi(api.Users.UserRegisterHandler))
}
- if config.EnableDataExport {
- dataRoute := apiRoute.Group("/data")
- dataRoute.Use(bindMiddleware(middlewares.HeaderInQueryString))
- dataRoute.Use(bindMiddleware(middlewares.JWTAuthorizationByQueryString))
- {
- dataRoute.GET("/export.csv", bindCsv(api.DataManagements.ExportDataHandler))
- }
- }
-
apiRoute.GET("/logout.json", bindApi(api.Tokens.TokenRevokeCurrentHandler))
apiV1Route := apiRoute.Group("/v1")
@@ -190,6 +181,10 @@ func startWebServer(c *cli.Context) error {
apiV1Route.GET("/data/statistics.json", bindApi(api.DataManagements.DataStatisticsHandler))
apiV1Route.POST("/data/clear.json", bindApi(api.DataManagements.ClearDataHandler))
+ if config.EnableDataExport {
+ apiV1Route.GET("/data/export.csv", bindCsv(api.DataManagements.ExportDataHandler))
+ }
+
// Accounts
apiV1Route.GET("/accounts/list.json", bindApi(api.Accounts.AccountListHandler))
apiV1Route.GET("/accounts/get.json", bindApi(api.Accounts.AccountGetHandler))
diff --git a/pkg/middlewares/authorization.go b/pkg/middlewares/authorization.go
index 6161bc95..6d5e429f 100644
--- a/pkg/middlewares/authorization.go
+++ b/pkg/middlewares/authorization.go
@@ -37,21 +37,6 @@ func JWTAuthorization(c *core.Context) {
c.Next()
}
-// JWTAuthorizationByQueryString verifies whether current request is valid by jwt token
-func JWTAuthorizationByQueryString(c *core.Context) {
- token, exists := c.GetQuery(tokenQueryStringParam)
-
- if !exists {
- log.WarnfWithRequestId(c, "[authorization.JWTAuthorizationByQueryString] no token provided")
- utils.PrintJsonErrorResult(c, errs.ErrUnauthorizedAccess)
- return
- }
-
- c.Request.Header.Set("Authorization", token)
-
- JWTAuthorization(c)
-}
-
// JWTTwoFactorAuthorization verifies whether current request is valid by 2fa passcode
func JWTTwoFactorAuthorization(c *core.Context) {
claims, err := getTokenClaims(c)
diff --git a/pkg/middlewares/header_in_query_string.go b/pkg/middlewares/header_in_query_string.go
deleted file mode 100644
index fdd7fe77..00000000
--- a/pkg/middlewares/header_in_query_string.go
+++ /dev/null
@@ -1,16 +0,0 @@
-package middlewares
-
-import (
- "github.com/mayswind/ezbookkeeping/pkg/core"
-)
-
-const utcOffsetQueryStringParam = "utc_offset"
-
-// HeaderInQueryString puts some headers from query string
-func HeaderInQueryString(c *core.Context) {
- utcOffset, exists := c.GetQuery(utcOffsetQueryStringParam)
-
- if exists {
- c.Request.Header.Set(core.ClientTimezoneOffsetHeaderName, utcOffset)
- }
-}
diff --git a/src/lib/services.js b/src/lib/services.js
index 6c7a8288..8f9ce7c3 100644
--- a/src/lib/services.js
+++ b/src/lib/services.js
@@ -170,6 +170,9 @@ export default {
getUserDataStatistics: () => {
return axios.get('v1/data/statistics.json');
},
+ getExportedUserData: () => {
+ return axios.get('v1/data/export.csv');
+ },
clearData: ({ password }) => {
return axios.post('v1/data/clear.json', {
password
diff --git a/src/locales/en.js b/src/locales/en.js
index b69886d8..8c9018b5 100644
--- a/src/locales/en.js
+++ b/src/locales/en.js
@@ -41,6 +41,10 @@ export default {
'long': 'm/d/yyyy hh::mm A',
},
},
+ 'dataExport': {
+ 'defaultExportFilename': 'ezBookkeeping_export_data',
+ 'exportFilename': 'ezBookkeeping_{nickname}_export_data'
+ },
'datetime': {
'Monday': {
'min': 'Mo',
@@ -591,6 +595,7 @@ export default {
'transaction tag name is empty': 'Transaction tag title is empty',
'transaction tag name already exists': 'Transaction tag title already exists',
'transaction tag is in use and cannot be deleted': 'Transaction tag is in use and it cannot be deleted',
+ 'data export not allowed': 'User data export is not allowed',
'query items cannot be empty': 'There are no query items',
'query items too much': 'There are too many query items',
'query items have invalid item': 'There is invalid item in query items',
@@ -901,6 +906,10 @@ export default {
'Unable to get user statistics data': 'Unable to get user statistics data',
'Export Data': 'Export Data',
'Clear User Data': 'Clear User Data',
+ 'Are you sure you want to export all data to csv file?': 'Are you sure you want to export all data to csv file?',
+ 'It may take a long time, please wait for a few minutes.': 'It may take a long time, please wait for a few minutes.',
+ 'Unable to get exported user data': 'Unable to get exported user data',
+ 'Save Data': 'Save Data',
'Are you sure you want to clear all data?': 'Are you sure you want to clear all data?',
'You CANNOT undo this action. This will clear your accounts, categories, tags and transactions data. Please input your current password to confirm.': 'You CANNOT undo this action. This will clear your accounts, categories, tags and transactions data. Please input your current password to confirm.',
'All user data has been cleared': 'All user data has been cleared',
diff --git a/src/locales/zh_Hans.js b/src/locales/zh_Hans.js
index 3e57bfad..154de58f 100644
--- a/src/locales/zh_Hans.js
+++ b/src/locales/zh_Hans.js
@@ -41,6 +41,10 @@ export default {
'long': 'yyyy年m月d日 HH::mm',
},
},
+ 'dataExport': {
+ 'defaultExportFilename': 'ezBookkeeping_导出数据',
+ 'exportFilename': 'ezBookkeeping_{nickname}_导出数据'
+ },
'datetime': {
'Monday': {
'min': '一',
@@ -591,6 +595,7 @@ export default {
'transaction tag name is empty': '交易标签标题不能为空',
'transaction tag name already exists': '交易标签标题已经存在',
'transaction tag is in use and cannot be deleted': '交易标签正在被使用,无法删除',
+ 'data export not allowed': '不允许用户数据导出',
'query items cannot be empty': '请求项目不能为空',
'query items too much': '请求项目过多',
'query items have invalid item': '请求项目中有非法项目',
@@ -901,6 +906,10 @@ export default {
'Unable to get user statistics data': '无法获取用户统计数据',
'Export Data': '导出数据',
'Clear User Data': '清除用户数据',
+ 'Are you sure you want to export all data to csv file?': '您确定要导出所有数据到 csv 文件?',
+ 'It may take a long time, please wait for a few minutes.': '这可能花费一些时间,请稍等几分钟。',
+ 'Unable to get exported user data': '无法获取导出的用户数据',
+ 'Save Data': '保存数据',
'Are you sure you want to clear all data?': '您确定要清除所有数据?',
'You CANNOT undo this action. This will clear your accounts, categories, tags and transactions data. Please input your current password to confirm.': '您不能撤销该操作。该操作将会清除您的账户、分类、标签以及交易数据。请输入您当前的密码以确认。',
'All user data has been cleared': '用户所有数据已经清空',
diff --git a/src/store/index.js b/src/store/index.js
index 084c5511..a500c447 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -68,6 +68,7 @@ import {
getCurrentUserProfile,
updateUserProfile,
getUserDataStatistics,
+ getExportedUserData,
clearUserData,
clearUserInfoState,
resetState,
@@ -947,6 +948,7 @@ const stores = {
getCurrentUserProfile,
updateUserProfile,
getUserDataStatistics,
+ getExportedUserData,
clearUserData,
clearUserInfoState,
resetState,
diff --git a/src/store/user.js b/src/store/user.js
index 310f2390..5d30c99f 100644
--- a/src/store/user.js
+++ b/src/store/user.js
@@ -307,6 +307,30 @@ export function getUserDataStatistics() {
});
}
+export function getExportedUserData() {
+ return new Promise((resolve, reject) => {
+ services.getExportedUserData().then(response => {
+ if (response && response.headers && response.headers['content-type'] !== 'text/csv') {
+ reject({ message: 'Unable to get exported user data' });
+ return;
+ }
+
+ const blob = new Blob([response.data], { type: response.headers['content-type'] });
+ resolve(blob);
+ }).catch(error => {
+ logger.error('failed to get user statistics data', error);
+
+ if (error.response.headers['content-type'] === 'text/text' && error.response && error.response.data) {
+ reject({ message: 'error.' + error.response.data });
+ } else if (!error.processed) {
+ reject({ message: 'Unable to get exported user data' });
+ } else {
+ reject(error);
+ }
+ });
+ });
+}
+
export function clearUserData(context, { password }) {
return new Promise((resolve, reject) => {
services.clearData({
diff --git a/src/views/mobile/users/DataManagement.vue b/src/views/mobile/users/DataManagement.vue
index 127972ca..6642a630 100644
--- a/src/views/mobile/users/DataManagement.vue
+++ b/src/views/mobile/users/DataManagement.vue
@@ -27,12 +27,28 @@
- {{ $t('Export Data') }}
+ {{ $t('Export Data') }}{{ $t('Clear User Data') }}
+
+
+
+
{{ $t('Are you sure you want to export all data to csv file?') }}
+
+
+
{{ $t('It may take a long time, please wait for a few minutes.') }}