diff --git a/api/auth_api.py b/api/auth_api.py index c78e27f..619f8d9 100644 --- a/api/auth_api.py +++ b/api/auth_api.py @@ -159,3 +159,8 @@ def me(): except jwt.InvalidTokenError: return jsonify({'error': 'Invalid token', 'code': INVALID_TOKEN}), 401 +@auth_api.route('/logout', methods=['POST']) +def logout(): + resp = jsonify({'message': 'Logged out'}) + resp.set_cookie('token', '', expires=0, httponly=True, secure=True, samesite='Strict') + return resp, 200 diff --git a/web/vue-app/src/components/LoginButton.vue b/web/vue-app/src/components/LoginButton.vue index c0c2b96..ae4e9a2 100644 --- a/web/vue-app/src/components/LoginButton.vue +++ b/web/vue-app/src/components/LoginButton.vue @@ -9,6 +9,7 @@ const show = ref(false) const pin = ref('') const error = ref('') const pinInput = ref(null) +const dropdownOpen = ref(false) const open = async () => { pin.value = '' @@ -46,6 +47,21 @@ const handleLogout = () => { router.push('/child') } +function toggleDropdown() { + dropdownOpen.value = !dropdownOpen.value +} + +async function signOut() { + try { + await fetch('/api/logout', { method: 'POST' }) + logoutParent() + router.push('/auth') + } catch { + // Optionally show error + } + dropdownOpen.value = false +} + onMounted(() => { eventBus.on('open-login', open) }) @@ -55,13 +71,42 @@ onUnmounted(() => {