feat: logged in users exports
This commit is contained in:
parent
b1109c2ceb
commit
45d1a9a2bd
|
@ -244,7 +244,10 @@
|
||||||
},
|
},
|
||||||
"label": "Profile"
|
"label": "Profile"
|
||||||
},
|
},
|
||||||
"select_a_settings": "Select a settings"
|
"select_a_settings": "Select a settings",
|
||||||
|
"users": {
|
||||||
|
"label": "Logged in users"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"state": {
|
"state": {
|
||||||
"edited": "(Edited)",
|
"edited": "(Edited)",
|
||||||
|
|
|
@ -70,6 +70,7 @@
|
||||||
"@iconify-json/twemoji": "^1.1.7",
|
"@iconify-json/twemoji": "^1.1.7",
|
||||||
"@nuxtjs/i18n": "^8.0.0-beta.7",
|
"@nuxtjs/i18n": "^8.0.0-beta.7",
|
||||||
"@pinia/nuxt": "^0.4.6",
|
"@pinia/nuxt": "^0.4.6",
|
||||||
|
"@types/file-saver": "^2.0.5",
|
||||||
"@types/fnando__sparkline": "^0.3.4",
|
"@types/fnando__sparkline": "^0.3.4",
|
||||||
"@types/fs-extra": "^9.0.13",
|
"@types/fs-extra": "^9.0.13",
|
||||||
"@types/js-yaml": "^4.0.5",
|
"@types/js-yaml": "^4.0.5",
|
||||||
|
@ -83,6 +84,7 @@
|
||||||
"emoji-mart": "^5.4.0",
|
"emoji-mart": "^5.4.0",
|
||||||
"eslint": "^8.30.0",
|
"eslint": "^8.30.0",
|
||||||
"esno": "^0.16.3",
|
"esno": "^0.16.3",
|
||||||
|
"file-saver": "^2.0.5",
|
||||||
"fs-extra": "^11.1.0",
|
"fs-extra": "^11.1.0",
|
||||||
"jsdom": "^20.0.3",
|
"jsdom": "^20.0.3",
|
||||||
"lint-staged": "^13.1.0",
|
"lint-staged": "^13.1.0",
|
||||||
|
|
|
@ -43,6 +43,12 @@ const isRootPath = computedEager(() => route.name === 'settings')
|
||||||
:text="$t('settings.preferences.label')"
|
:text="$t('settings.preferences.label')"
|
||||||
to="/settings/preferences"
|
to="/settings/preferences"
|
||||||
/>
|
/>
|
||||||
|
<SettingsNavItem
|
||||||
|
command
|
||||||
|
icon="i-ri-group-line"
|
||||||
|
:text="$t('settings.users.label')"
|
||||||
|
to="/settings/users"
|
||||||
|
/>
|
||||||
<SettingsNavItem
|
<SettingsNavItem
|
||||||
command
|
command
|
||||||
icon="i-ri:information-line"
|
icon="i-ri:information-line"
|
||||||
|
|
89
pages/settings/users/index.vue
Normal file
89
pages/settings/users/index.vue
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { UserLogin } from '~/types'
|
||||||
|
|
||||||
|
const { lg } = breakpoints
|
||||||
|
|
||||||
|
const loggedInUsers = useUsers()
|
||||||
|
|
||||||
|
async function exportTokens() {
|
||||||
|
if (!confirm('Please aware that the tokens represent the **full access** to your accounts, and should be treated as sensitive information. Are you sure you want to export the tokens?'))
|
||||||
|
return
|
||||||
|
|
||||||
|
const { saveAs } = await import('file-saver')
|
||||||
|
const data = {
|
||||||
|
'/': 'Generated by Elk, you can import it to Elk to restore the tokens.',
|
||||||
|
'//': 'This file represents the **full access** to your accounts, and should be treated as sensitive information.',
|
||||||
|
'version': 1,
|
||||||
|
'origin': location.origin,
|
||||||
|
'users': loggedInUsers.value,
|
||||||
|
}
|
||||||
|
const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json;charset=utf-8' })
|
||||||
|
saveAs(blob, `elk-users-tokens-${new Date().toISOString().slice(0, 10)}.json`)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function importTokens() {
|
||||||
|
const input = document.createElement('input') as HTMLInputElement
|
||||||
|
input.type = 'file'
|
||||||
|
input.accept = 'application/json'
|
||||||
|
input.multiple = false
|
||||||
|
|
||||||
|
input.addEventListener('change', async (e) => {
|
||||||
|
const file = (e.target as any)?.files?.[0] as File
|
||||||
|
if (!file)
|
||||||
|
return
|
||||||
|
|
||||||
|
try {
|
||||||
|
const content = await file.text()
|
||||||
|
const data = JSON.parse(content)
|
||||||
|
if (data.version !== 1)
|
||||||
|
throw new Error('Invalid version')
|
||||||
|
const users = data.users as UserLogin[]
|
||||||
|
const newUsers: UserLogin[] = []
|
||||||
|
for (const user of users) {
|
||||||
|
if (loggedInUsers.value.some(u => u.server === user.server && u.account.id === user.account.id))
|
||||||
|
continue
|
||||||
|
newUsers.push(user)
|
||||||
|
}
|
||||||
|
if (newUsers.length === 0) {
|
||||||
|
alert('No new users found')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!confirm(`Found ${newUsers.length} new users, are you sure you want to import them?`))
|
||||||
|
return
|
||||||
|
loggedInUsers.value = [...loggedInUsers.value, ...newUsers]
|
||||||
|
}
|
||||||
|
catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
alert('Invalid Elk tokens file')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
input.click()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<MainContent :back="!lg">
|
||||||
|
<template #title>
|
||||||
|
<div text-lg font-bold flex items-center gap-2 @click="$scrollToTop">
|
||||||
|
<span>{{ $t('settings.users.label') }}</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<div p4>
|
||||||
|
<div flex="~ col gap2">
|
||||||
|
<div v-for="user of loggedInUsers" :key="user.account.id">
|
||||||
|
<AccountInfo :account="user.account" :hover-card="false" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div my4 border="t base" />
|
||||||
|
<button btn-text flex="~ gap-2" items-center @click="exportTokens">
|
||||||
|
<div i-ri-download-2-line />
|
||||||
|
Export User Tokens
|
||||||
|
</button>
|
||||||
|
<button btn-text flex="~ gap-2" items-center @click="importTokens">
|
||||||
|
<div i-ri-upload-2-line />
|
||||||
|
Import User Tokens
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</MainContent>
|
||||||
|
</template>
|
|
@ -22,6 +22,7 @@ specifiers:
|
||||||
'@tiptap/starter-kit': 2.0.0-beta.204
|
'@tiptap/starter-kit': 2.0.0-beta.204
|
||||||
'@tiptap/suggestion': 2.0.0-beta.204
|
'@tiptap/suggestion': 2.0.0-beta.204
|
||||||
'@tiptap/vue-3': 2.0.0-beta.204
|
'@tiptap/vue-3': 2.0.0-beta.204
|
||||||
|
'@types/file-saver': ^2.0.5
|
||||||
'@types/fnando__sparkline': ^0.3.4
|
'@types/fnando__sparkline': ^0.3.4
|
||||||
'@types/fs-extra': ^9.0.13
|
'@types/fs-extra': ^9.0.13
|
||||||
'@types/js-yaml': ^4.0.5
|
'@types/js-yaml': ^4.0.5
|
||||||
|
@ -39,6 +40,7 @@ specifiers:
|
||||||
emoji-mart: ^5.4.0
|
emoji-mart: ^5.4.0
|
||||||
eslint: ^8.30.0
|
eslint: ^8.30.0
|
||||||
esno: ^0.16.3
|
esno: ^0.16.3
|
||||||
|
file-saver: ^2.0.5
|
||||||
floating-vue: 2.0.0-beta.20
|
floating-vue: 2.0.0-beta.20
|
||||||
focus-trap: ^7.2.0
|
focus-trap: ^7.2.0
|
||||||
form-data: ^4.0.0
|
form-data: ^4.0.0
|
||||||
|
@ -122,6 +124,7 @@ devDependencies:
|
||||||
'@iconify-json/twemoji': 1.1.7
|
'@iconify-json/twemoji': 1.1.7
|
||||||
'@nuxtjs/i18n': 8.0.0-beta.7
|
'@nuxtjs/i18n': 8.0.0-beta.7
|
||||||
'@pinia/nuxt': 0.4.6_typescript@4.9.4
|
'@pinia/nuxt': 0.4.6_typescript@4.9.4
|
||||||
|
'@types/file-saver': 2.0.5
|
||||||
'@types/fnando__sparkline': 0.3.4
|
'@types/fnando__sparkline': 0.3.4
|
||||||
'@types/fs-extra': 9.0.13
|
'@types/fs-extra': 9.0.13
|
||||||
'@types/js-yaml': 4.0.5
|
'@types/js-yaml': 4.0.5
|
||||||
|
@ -135,6 +138,7 @@ devDependencies:
|
||||||
emoji-mart: 5.4.0
|
emoji-mart: 5.4.0
|
||||||
eslint: 8.30.0
|
eslint: 8.30.0
|
||||||
esno: 0.16.3
|
esno: 0.16.3
|
||||||
|
file-saver: 2.0.5
|
||||||
fs-extra: 11.1.0
|
fs-extra: 11.1.0
|
||||||
jsdom: 20.0.3
|
jsdom: 20.0.3
|
||||||
lint-staged: 13.1.0
|
lint-staged: 13.1.0
|
||||||
|
@ -2652,6 +2656,10 @@ packages:
|
||||||
resolution: {integrity: sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==}
|
resolution: {integrity: sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@types/file-saver/2.0.5:
|
||||||
|
resolution: {integrity: sha512-zv9kNf3keYegP5oThGLaPk8E081DFDuwfqjtiTzm6PoxChdJ1raSuADf2YGCVIyrSynLrgc8JWv296s7Q7pQSQ==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@types/fnando__sparkline/0.3.4:
|
/@types/fnando__sparkline/0.3.4:
|
||||||
resolution: {integrity: sha512-FWU1zw7CVJYVeDk77FGphTUabfPims4F/Yq+WFB0Gh647lLtiXHWn8vpfT95Fl65IsNBDOhEbxJdhmERMGubNQ==}
|
resolution: {integrity: sha512-FWU1zw7CVJYVeDk77FGphTUabfPims4F/Yq+WFB0Gh647lLtiXHWn8vpfT95Fl65IsNBDOhEbxJdhmERMGubNQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -5692,6 +5700,10 @@ packages:
|
||||||
flat-cache: 3.0.4
|
flat-cache: 3.0.4
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/file-saver/2.0.5:
|
||||||
|
resolution: {integrity: sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/file-uri-to-path/1.0.0:
|
/file-uri-to-path/1.0.0:
|
||||||
resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
|
resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
Loading…
Reference in a new issue