Skip to content

Commit

Permalink
fix multi byte strings in history encryption + test
Browse files Browse the repository at this point in the history
  • Loading branch information
joetannenbaum committed Oct 14, 2024
1 parent 88a765b commit 541529e
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 5 deletions.
6 changes: 3 additions & 3 deletions packages/core/src/encryption.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,17 +47,17 @@ const encryptData = async (iv: Uint8Array, key: CryptoKey, data: any) => {

const textEncoder = new TextEncoder()
const str = JSON.stringify(data)
const encoded = new Uint8Array(str.length)
const encoded = new Uint8Array(str.length * 3)

textEncoder.encodeInto(str, encoded)
const result = textEncoder.encodeInto(str, encoded)

return window.crypto.subtle.encrypt(
{
name: 'AES-GCM',
iv,
},
key,
encoded,
encoded.subarray(0, result.written),
)
}

Expand Down
4 changes: 3 additions & 1 deletion packages/vue3/test-app/Pages/History/Page.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
<script setup lang="ts">
import { Link, router } from '@inertiajs/vue3'
defineProps<{ pageNumber: number }>()
defineProps<{ pageNumber: number; multiByte: string }>()
</script>

<template>
<Link href="/history/1">Page 1</Link>
<Link href="/history/2">Page 2</Link>
<Link href="/history/3">Page 3</Link>
<Link href="/history/4">Page 4</Link>
<Link href="/history/5">Page 5</Link>

<button @click="router.clearHistory()">Clear History</button>

<div>This is page {{ pageNumber }}.</div>
<div>Multi byte character: {{ multiByte }}</div>
</template>
3 changes: 2 additions & 1 deletion tests/app/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,9 @@ app.get('/history/:pageNumber', (req, res) => {
component: 'History/Page',
props: {
pageNumber: req.params.pageNumber,
multiByte: req.params.pageNumber === '5' ? '😃' : 'n/a',
},
encryptHistory: req.params.pageNumber === '3',
encryptHistory: req.params.pageNumber === '3' || req.params.pageNumber === '5',
clearHistory: req.params.pageNumber === '4',
})
})
Expand Down
23 changes: 23 additions & 0 deletions tests/history.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,26 @@ test('history can be cleared via props', async ({ page }) => {
await page.waitForURL('/history/3')
await expect(requests.requests).toHaveLength(1)
})

test('multi byte strings can be encrypyed', async ({ page }) => {
await clickAndWaitForResponse(page, 'Page 5', '/history/5')
const historyState5 = await page.evaluate(() => window.history.state)
// When history is encrypted, the page is an ArrayBuffer,
// but Playwright doesn't transfer it as such over the wire (page.evaluate),
// so if the object is "empty" and the page check below works, it's working.
await expect(historyState5.page).toEqual({})
await expect(historyState5.timestamp).toBeGreaterThan(0)
await expect(page.getByText('Multi byte character: 😃')).toBeVisible()

await clickAndWaitForResponse(page, 'Page 1', '/history/1')

await expect(page.getByText('Multi byte character: n/a')).toBeVisible()

requests.listen(page)

await page.goBack()
await page.waitForURL('/history/5')
await expect(page.getByText('This is page 5')).toBeVisible()
await expect(requests.requests).toHaveLength(0)
await expect(page.getByText('Multi byte character: 😃')).toBeVisible()
})

0 comments on commit 541529e

Please sign in to comment.