3 Commits
v1.2.0 ... main

4 changed files with 68 additions and 36 deletions

View File

@@ -271,6 +271,18 @@ async def update_user(request, username):
return json(response)
@bp.delete("/users/<username>")
async def delete_user(request, username):
verify(request, privileged=True)
if username not in config.config.users:
raise BadRequest("User does not exist")
try:
config.del_user(username)
except Exception as e:
raise BadRequest(str(e)) from e
return json({"message": f"User {username} deleted"})
@bp.put("/config/public")
async def update_public(request):
verify(request, privileged=True)

View File

@@ -78,7 +78,7 @@ const filesystemdl = async (sel: SelectedItems, handle: FileSystemDirectoryHandl
h = await h.getDirectoryHandle(dir.normalize('NFC'), { create: true })
} catch (error) {
console.error('Failed to create directory', hdir, error)
return
throw new Error(`Failed to create directory ${hdir}: ${error}`)
}
console.log('Created', hdir)
}
@@ -90,8 +90,9 @@ const filesystemdl = async (sel: SelectedItems, handle: FileSystemDirectoryHandl
fileHandle = await h.getFileHandle(name, { create: true })
} catch (error) {
console.error('Failed to create file', rel, full, hdir + name, error)
return
throw new Error(`Failed to create file ${hdir + name}: ${error}`)
}
try {
const writable = await fileHandle.createWritable()
const url = `/files/${rel}`
console.log('Fetching', url)
@@ -121,6 +122,10 @@ const filesystemdl = async (sel: SelectedItems, handle: FileSystemDirectoryHandl
}
await writable.close()
console.log('Saved', hdir + name)
} catch (error) {
console.error('Failed to write file', hdir + name, error)
throw new Error(`Failed to write file ${hdir + name}: ${error}`)
}
}
statReset()
}

View File

@@ -14,9 +14,9 @@
</div>
<h3>Users</h3>
<button @click="addUser" class="button" title="Add new user"> Add User</button>
<div v-if="success" class="success-message">
<div v-if="success" class="success-message" @click="copySuccess(false)">
{{ success }}
<button @click="copySuccess" class="button small" title="Copy to clipboard"><EFBFBD></button>
<button v-if="success.includes('Password:') || success.includes('New password:')" @click.stop="copySuccess(true)" class="button small" title="Copy to clipboard">{{ copyButtonText }}</button>
</div>
<table class="user-table">
<thead>
@@ -70,6 +70,7 @@ const loading = ref(true)
const users = ref<User[]>([])
const error = ref('')
const success = ref('')
const copyButtonText = ref('📋')
const serverSettings = reactive({
public: false
})
@@ -170,11 +171,25 @@ const deleteUserAction = async (username: string) => {
}
}
const copySuccess = async () => {
const passwordMatch = success.value.match(/Password: (.+)/)
const copySuccess = async (isButtonClick: boolean = false) => {
const passwordMatch = success.value.match(/(?:Password|New password): (.+)/)
if (passwordMatch) {
await navigator.clipboard.writeText(passwordMatch[1])
// Maybe flash or something, but for now just copy
if (isButtonClick) {
// Show "Copied!" indication on button
copyButtonText.value = '✅ Copied!'
// Hide password and button immediately after copying
const baseMessage = success.value.replace(/(?:Password|New password): .+/, 'Password copied to clipboard!')
success.value = baseMessage
// Hide the entire message after 3 seconds
setTimeout(() => {
success.value = ''
copyButtonText.value = '📋'
}, 3000)
} else {
// Just hide the message when clicking elsewhere
success.value = ''
}
}
}

View File

@@ -73,8 +73,8 @@ watchEffect(() => {
store.query = props.query
})
watch(documents, (docs) => {
store.prefs.gallery = docs.some(d => d.previewable)
watch([() => props.path.join('/'), () => props.query], () => {
store.prefs.gallery = documents.value.some(d => d.previewable)
}, { immediate: true })
</script>