fix(guest): move guest token from URL query to sessionStorage (#21) #28

Open
hermes wants to merge 1 commit from fix/guest-token-session-storage into master
5 changed files with 36 additions and 15 deletions

View file

@ -158,8 +158,9 @@ describe('GuestCheckoutPage', () => {
await vi.waitFor(() => {
expect(router.currentRoute.value.name).toBe('guest-payment')
expect(router.currentRoute.value.params.orderId).toBe('order-123')
expect(router.currentRoute.value.query.token).toBe('token-abc')
expect(router.currentRoute.value.query.token).toBeUndefined()
expect(router.currentRoute.value.query.plate).toBe('ABC123')
expect(sessionStorage.getItem('guestToken')).toBe('token-abc')
})
})

View file

@ -67,13 +67,20 @@ async function mountPage(
Review

💡 Suggestion: The backward-compat fallback (sessionStorage.getItem('guestToken') || route.query.token) is untested. Consider adding a test case where mountPage is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.

💡 **Suggestion**: The backward-compat fallback (`sessionStorage.getItem('guestToken') || route.query.token`) is untested. Consider adding a test case where `mountPage` is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.
Review

💡 Suggestion: The backward-compat fallback (sessionStorage.getItem('guestToken') || route.query.token) is untested. Consider adding a test case where mountPage is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.

💡 **Suggestion**: The backward-compat fallback (`sessionStorage.getItem('guestToken') || route.query.token`) is untested. Consider adding a test case where `mountPage` is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.
token = 'token-abc',
plate = 'ABC123',
) {
// Store token in sessionStorage as GuestCheckoutPage and GuestOrderPage do
Review

💡 Suggestion: The backward-compat fallback (sessionStorage.getItem('guestToken') || route.query.token) is untested. Consider adding a test case where mountPage is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.

💡 **Suggestion**: The backward-compat fallback (`sessionStorage.getItem('guestToken') || route.query.token`) is untested. Consider adding a test case where `mountPage` is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.
if (token) {
Review

💡 Suggestion: The backward-compat fallback (sessionStorage.getItem('guestToken') || route.query.token) is untested. Consider adding a test case where mountPage is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.

💡 **Suggestion**: The backward-compat fallback (`sessionStorage.getItem('guestToken') || route.query.token`) is untested. Consider adding a test case where `mountPage` is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.
sessionStorage.setItem('guestToken', token)
Review

💡 Suggestion: The backward-compat fallback (sessionStorage.getItem('guestToken') || route.query.token) is untested. Consider adding a test case where mountPage is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.

💡 **Suggestion**: The backward-compat fallback (`sessionStorage.getItem('guestToken') || route.query.token`) is untested. Consider adding a test case where `mountPage` is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.
} else {
Review

💡 Suggestion: The backward-compat fallback (sessionStorage.getItem('guestToken') || route.query.token) is untested. Consider adding a test case where mountPage is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.

💡 **Suggestion**: The backward-compat fallback (`sessionStorage.getItem('guestToken') || route.query.token`) is untested. Consider adding a test case where `mountPage` is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.
sessionStorage.removeItem('guestToken')
Review

💡 Suggestion: The backward-compat fallback (sessionStorage.getItem('guestToken') || route.query.token) is untested. Consider adding a test case where mountPage is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.

💡 **Suggestion**: The backward-compat fallback (`sessionStorage.getItem('guestToken') || route.query.token`) is untested. Consider adding a test case where `mountPage` is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.
}
Review

💡 Suggestion: The backward-compat fallback (sessionStorage.getItem('guestToken') || route.query.token) is untested. Consider adding a test case where mountPage is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.

💡 **Suggestion**: The backward-compat fallback (`sessionStorage.getItem('guestToken') || route.query.token`) is untested. Consider adding a test case where `mountPage` is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.
Review

💡 Suggestion: The backward-compat fallback (sessionStorage.getItem('guestToken') || route.query.token) is untested. Consider adding a test case where mountPage is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.

💡 **Suggestion**: The backward-compat fallback (`sessionStorage.getItem('guestToken') || route.query.token`) is untested. Consider adding a test case where `mountPage` is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.
const pinia = createPinia()
setActivePinia(pinia)
const router = createTestRouter()
await router.push({
name: 'guest-payment',
params: { orderId },
query: { token, plate },
Review

💡 Suggestion: The backward-compat fallback (sessionStorage.getItem('guestToken') || route.query.token) is untested. Consider adding a test case where mountPage is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.

💡 **Suggestion**: The backward-compat fallback (`sessionStorage.getItem('guestToken') || route.query.token`) is untested. Consider adding a test case where `mountPage` is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.
query: { plate },
Review

💡 Suggestion: The backward-compat fallback (sessionStorage.getItem('guestToken') || route.query.token) is untested. Consider adding a test case where mountPage is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.

💡 **Suggestion**: The backward-compat fallback (`sessionStorage.getItem('guestToken') || route.query.token`) is untested. Consider adding a test case where `mountPage` is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.
})
await router.isReady()
@ -99,6 +106,7 @@ function setupDefaultMocks() {
Review

💡 Suggestion: The backward-compat fallback (sessionStorage.getItem('guestToken') || route.query.token) is untested. Consider adding a test case where mountPage is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.

💡 **Suggestion**: The backward-compat fallback (`sessionStorage.getItem('guestToken') || route.query.token`) is untested. Consider adding a test case where `mountPage` is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.
Review

💡 Suggestion: The backward-compat fallback (sessionStorage.getItem('guestToken') || route.query.token) is untested. Consider adding a test case where mountPage is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.

💡 **Suggestion**: The backward-compat fallback (`sessionStorage.getItem('guestToken') || route.query.token`) is untested. Consider adding a test case where `mountPage` is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.
describe('GuestPaymentRedirect', () => {
beforeEach(() => {
vi.clearAllMocks()
sessionStorage.clear()
Review

💡 Suggestion: The backward-compat fallback (sessionStorage.getItem('guestToken') || route.query.token) is untested. Consider adding a test case where mountPage is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.

💡 **Suggestion**: The backward-compat fallback (`sessionStorage.getItem('guestToken') || route.query.token`) is untested. Consider adding a test case where `mountPage` is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.
setupDefaultMocks()
})

Review

💡 Suggestion: The backward-compat fallback (sessionStorage.getItem('guestToken') || route.query.token) is untested. Consider adding a test case where mountPage is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.

💡 **Suggestion**: The backward-compat fallback (`sessionStorage.getItem('guestToken') || route.query.token`) is untested. Consider adding a test case where `mountPage` is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.
Review

💡 Suggestion: The backward-compat fallback (sessionStorage.getItem('guestToken') || route.query.token) is untested. Consider adding a test case where mountPage is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.

💡 **Suggestion**: The backward-compat fallback (`sessionStorage.getItem('guestToken') || route.query.token`) is untested. Consider adding a test case where `mountPage` is called with the token in the route query but sessionStorage cleared, to verify the fallback works for old bookmarked URLs.

View file

@ -37,11 +37,14 @@ async function handleSubmit() {
letterText.value,
email.value.trim(),
)
// Token rides in the query string so the payment page survives refresh.
// Store the guest token in sessionStorage so it does not leak via the URL
// query string (browser history, access logs, Referer). sessionStorage
// persists across page refreshes within the same tab.
sessionStorage.setItem('guestToken', order.guestToken)
await router.push({
name: 'guest-payment',
params: { orderId: order.id },
query: { token: order.guestToken, plate: order.plate },
query: { plate: order.plate },
})
} catch {
errorMessage.value = 'Kunde inte skapa beställningen. Försök igen senare.'

View file

@ -1,9 +1,10 @@
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { useRoute } from 'vue-router'
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
import { useRoute, useRouter } from 'vue-router'
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
import { fetchGuestOrder, type GuestOrder } from '@/api/guestOrders'
const route = useRoute()
const router = useRouter()
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
const token = route.params.token as string
const order = ref<GuestOrder | null>(null)
@ -45,6 +46,18 @@ onMounted(async () => {
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
loading.value = false
}
})
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
function goToPayment() {
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
if (!order.value) return
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
// Store the guest token in sessionStorage so it does not leak via the URL
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
// query string on the payment page.
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
sessionStorage.setItem('guestToken', token)
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
router.push({
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
name: 'guest-payment',
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
params: { orderId: order.value.id },
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
query: { plate: order.value.plate },
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
})
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
}
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
</script>
<template>
@ -78,15 +91,7 @@ onMounted(async () => {
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
</div>
<p v-if="order.status === 'pending_payment'" class="guest-order__hint">
<RouterLink
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
:to="{
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
name: 'guest-payment',
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
params: { orderId: order.id },
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
query: { token, plate: order.plate },
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
}"
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
>
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
till betalningssidan
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
</RouterLink>
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
<a href="#" @click.prevent="goToPayment"> till betalningssidan </a>
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
</p>
<div class="guest-order__letter">

Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.
Review

💡 Suggestion: <a href="#" @click.prevent> degrades screen-reader semantics (a link to # / nowhere). A <button> styled to match, or keeping <RouterLink> with a custom navigation guard, would preserve accessibility without changing the visual result.

💡 **Suggestion**: `<a href="#" @click.prevent>` degrades screen-reader semantics (a link to `#` / nowhere). A `<button>` styled to match, or keeping `<RouterLink>` with a custom navigation guard, would preserve accessibility without changing the visual result.

View file

@ -9,7 +9,11 @@ const router = useRouter()
Review

💡 Suggestion: Consider sessionStorage.removeItem('guestToken') right after payGuestOrder(token) resolves, before the router.push. The token has been consumed at this point and lingering in sessionStorage only extends the credential's lifetime unnecessarily.

💡 **Suggestion**: Consider `sessionStorage.removeItem('guestToken')` right after `payGuestOrder(token)` resolves, before the `router.push`. The token has been consumed at this point and lingering in sessionStorage only extends the credential's lifetime unnecessarily.
Review

💡 Suggestion: Consider sessionStorage.removeItem('guestToken') right after payGuestOrder(token) resolves, before the router.push. The token has been consumed at this point and lingering in sessionStorage only extends the credential's lifetime unnecessarily.

💡 **Suggestion**: Consider `sessionStorage.removeItem('guestToken')` right after `payGuestOrder(token)` resolves, before the `router.push`. The token has been consumed at this point and lingering in sessionStorage only extends the credential's lifetime unnecessarily.
const route = useRoute()
const orderId = route.params.orderId as string
const token = (route.query.token as string) || ''
Review

💡 Suggestion: Consider sessionStorage.removeItem('guestToken') right after payGuestOrder(token) resolves, before the router.push. The token has been consumed at this point and lingering in sessionStorage only extends the credential's lifetime unnecessarily.

💡 **Suggestion**: Consider `sessionStorage.removeItem('guestToken')` right after `payGuestOrder(token)` resolves, before the `router.push`. The token has been consumed at this point and lingering in sessionStorage only extends the credential's lifetime unnecessarily.
// Read token from sessionStorage (set by the checkout/order pages) so it
Review

💡 Suggestion: Consider sessionStorage.removeItem('guestToken') right after payGuestOrder(token) resolves, before the router.push. The token has been consumed at this point and lingering in sessionStorage only extends the credential's lifetime unnecessarily.

💡 **Suggestion**: Consider `sessionStorage.removeItem('guestToken')` right after `payGuestOrder(token)` resolves, before the `router.push`. The token has been consumed at this point and lingering in sessionStorage only extends the credential's lifetime unnecessarily.
// does not leak via the URL query string. Fall back to query.token for
Review

💡 Suggestion: Consider sessionStorage.removeItem('guestToken') right after payGuestOrder(token) resolves, before the router.push. The token has been consumed at this point and lingering in sessionStorage only extends the credential's lifetime unnecessarily.

💡 **Suggestion**: Consider `sessionStorage.removeItem('guestToken')` right after `payGuestOrder(token)` resolves, before the `router.push`. The token has been consumed at this point and lingering in sessionStorage only extends the credential's lifetime unnecessarily.
// backward compatibility with any existing magic links.
Review

💡 Suggestion: Consider sessionStorage.removeItem('guestToken') right after payGuestOrder(token) resolves, before the router.push. The token has been consumed at this point and lingering in sessionStorage only extends the credential's lifetime unnecessarily.

💡 **Suggestion**: Consider `sessionStorage.removeItem('guestToken')` right after `payGuestOrder(token)` resolves, before the `router.push`. The token has been consumed at this point and lingering in sessionStorage only extends the credential's lifetime unnecessarily.
const token =
Review

💡 Suggestion: Consider sessionStorage.removeItem('guestToken') right after payGuestOrder(token) resolves, before the router.push. The token has been consumed at this point and lingering in sessionStorage only extends the credential's lifetime unnecessarily.

💡 **Suggestion**: Consider `sessionStorage.removeItem('guestToken')` right after `payGuestOrder(token)` resolves, before the `router.push`. The token has been consumed at this point and lingering in sessionStorage only extends the credential's lifetime unnecessarily.
sessionStorage.getItem('guestToken') || (route.query.token as string) || ''
Review

💡 Suggestion: Consider sessionStorage.removeItem('guestToken') right after payGuestOrder(token) resolves, before the router.push. The token has been consumed at this point and lingering in sessionStorage only extends the credential's lifetime unnecessarily.

💡 **Suggestion**: Consider `sessionStorage.removeItem('guestToken')` right after `payGuestOrder(token)` resolves, before the `router.push`. The token has been consumed at this point and lingering in sessionStorage only extends the credential's lifetime unnecessarily.
const plate = ref((route.query.plate as string) || '')
const swishNumber = ref('')

Review

💡 Suggestion: Consider sessionStorage.removeItem('guestToken') right after payGuestOrder(token) resolves, before the router.push. The token has been consumed at this point and lingering in sessionStorage only extends the credential's lifetime unnecessarily.

💡 **Suggestion**: Consider `sessionStorage.removeItem('guestToken')` right after `payGuestOrder(token)` resolves, before the `router.push`. The token has been consumed at this point and lingering in sessionStorage only extends the credential's lifetime unnecessarily.
Review

💡 Suggestion: Consider sessionStorage.removeItem('guestToken') right after payGuestOrder(token) resolves, before the router.push. The token has been consumed at this point and lingering in sessionStorage only extends the credential's lifetime unnecessarily.

💡 **Suggestion**: Consider `sessionStorage.removeItem('guestToken')` right after `payGuestOrder(token)` resolves, before the `router.push`. The token has been consumed at this point and lingering in sessionStorage only extends the credential's lifetime unnecessarily.