Skip to content

Commit 1c31a71

Browse files
committed
fix(gravatar): broken proxy
1 parent 3667588 commit 1c31a71

8 files changed

Lines changed: 474 additions & 103 deletions

File tree

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@
145145
"@nuxt/test-utils": "catalog:",
146146
"@nuxtjs/partytown": "catalog:",
147147
"@paypal/paypal-js": "catalog:",
148+
"@types/jest-image-snapshot": "^6.4.1",
148149
"@types/semver": "catalog:",
149150
"@types/youtube": "catalog:",
150151
"@typescript-eslint/typescript-estree": "catalog:",
@@ -153,6 +154,7 @@
153154
"eslint": "catalog:",
154155
"eslint-plugin-harlanzw": "catalog:",
155156
"happy-dom": "catalog:",
157+
"jest-image-snapshot": "^6.5.2",
156158
"knitwork": "catalog:",
157159
"nuxt": "catalog:",
158160
"playwright-core": "catalog:",

pnpm-lock.yaml

Lines changed: 414 additions & 99 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pnpm-workspace.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ catalog:
2525
consola: ^3.4.2
2626
defu: ^6.1.4
2727
eslint: ^10.0.3
28-
eslint-plugin-harlanzw: ^0.6.0
28+
eslint-plugin-harlanzw: ^0.6.1
2929
h3: ^1.15.8
3030
happy-dom: ^20.8.4
3131
knitwork: ^1.3.0
3232
magic-string: ^0.30.21
3333
nuxt: ^4.4.2
3434
ofetch: ^1.5.1
3535
ohash: ^2.0.11
36-
oxc-parser: ^0.120.0
36+
oxc-parser: ^0.121.0
3737
oxc-walker: ^0.7.0
3838
pathe: ^2.0.3
3939
pkg-types: ^2.3.0

src/runtime/server/gravatar-proxy.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ export default defineEventHandler(async (event) => {
3939
})
4040

4141
const response = await $fetch.raw(gravatarUrl, {
42-
responseType: 'arrayBuffer',
4342
headers: {
4443
'User-Agent': 'Nuxt Scripts Gravatar Proxy',
4544
},
2.91 KB
Loading
2.91 KB
Loading

test/e2e/basic.test.ts

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ describe('basic', () => {
178178
await page.waitForTimeout(500)
179179
// get content of #script-src
180180
const text = await page.$eval('#script-src', el => el.textContent)
181-
expect(text).toMatchInlineSnapshot(`"/_scripts/assets/6bEy8slcRmYcRT4E2QbQZ1CMyWw9PpHA7L87BtvSs2U.js"`)
181+
expect(text).toMatchInlineSnapshot(`"/_scripts/assets/PHzhM8DFXcXVSSJF110cyV3pjg9cp8oWv_f4Dk2ax1w.js"`)
182182
})
183183
it('partytown adds type attribute', async () => {
184184
const { page } = await createPage('/partytown')
@@ -234,6 +234,60 @@ describe('youtube', () => {
234234
})
235235
})
236236

237+
describe('gravatar', () => {
238+
async function expectImageSnapshot(buffer: Buffer, id: string) {
239+
const { toMatchImageSnapshot } = await import('jest-image-snapshot')
240+
expect.extend({ toMatchImageSnapshot })
241+
;(expect(buffer) as any).toMatchImageSnapshot({
242+
customSnapshotIdentifier: id,
243+
customSnapshotsDir: `${import.meta.dirname}/__image_snapshots__`,
244+
})
245+
}
246+
247+
it('proxy returns valid image for email lookup', {
248+
timeout: 15000,
249+
}, async () => {
250+
const response = await fetch(url('/_scripts/proxy/gravatar?email=test@example.com&s=80&d=identicon&r=g'))
251+
expect(response.status).toBe(200)
252+
expect(response.headers.get('content-type')).toContain('image/')
253+
expect(response.headers.get('cache-control')).toContain('public')
254+
255+
const buffer = Buffer.from(await response.arrayBuffer())
256+
expect(buffer.length).toBeGreaterThan(100)
257+
await expectImageSnapshot(buffer, 'gravatar-email-proxy')
258+
})
259+
260+
it('proxy returns valid image for hash lookup', {
261+
timeout: 15000,
262+
}, async () => {
263+
// SHA256 of "test@example.com"
264+
const hash = '973dfe463ec85785f5f95af5ba3906eedb2d931c24e69824a89ea65dba4e813b'
265+
const response = await fetch(url(`/_scripts/proxy/gravatar?hash=${hash}&s=80&d=identicon&r=g`))
266+
expect(response.status).toBe(200)
267+
expect(response.headers.get('content-type')).toContain('image/')
268+
269+
const buffer = Buffer.from(await response.arrayBuffer())
270+
expect(buffer.length).toBeGreaterThan(100)
271+
await expectImageSnapshot(buffer, 'gravatar-hash-proxy')
272+
})
273+
274+
it('email and hash proxy return identical images', {
275+
timeout: 15000,
276+
}, async () => {
277+
const hash = '973dfe463ec85785f5f95af5ba3906eedb2d931c24e69824a89ea65dba4e813b'
278+
const [emailRes, hashRes] = await Promise.all([
279+
fetch(url('/_scripts/proxy/gravatar?email=test@example.com&s=80&d=identicon&r=g')),
280+
fetch(url(`/_scripts/proxy/gravatar?hash=${hash}&s=80&d=identicon&r=g`)),
281+
])
282+
283+
const emailBuffer = Buffer.from(await emailRes.arrayBuffer())
284+
const hashBuffer = Buffer.from(await hashRes.arrayBuffer())
285+
286+
// Same email hashed server-side should produce identical image to pre-computed hash
287+
expect(emailBuffer.equals(hashBuffer)).toBe(true)
288+
})
289+
})
290+
237291
describe('third-party-capital', () => {
238292
it('expect GA to collect data', {
239293
timeout: 10000,

test/fixtures/basic/nuxt.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export default defineNuxtConfig({
99
xEmbed: true,
1010
instagramEmbed: true,
1111
blueskyEmbed: true,
12+
gravatar: true,
1213
},
1314
},
1415
devtools: {

0 commit comments

Comments
 (0)