a collection of lightweight TypeScript packages for AT Protocol, the protocol powering Bluesky
atproto bluesky typescript npm
101
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix(oauth-browser-client): only include URL origin and pathname in `htu` when signing DPoP requests

Mary a3f9e9b1 2b9f692c

+14 -7
+5
.changeset/swift-plants-turn.md
··· 1 + --- 2 + '@atcute/oauth-browser-client': patch 3 + --- 4 + 5 + only include URL origin and pathname in `htu` when signing DPoP requests
+9 -7
packages/oauth/browser-client/lib/dpop.ts
··· 26 26 27 27 const constructPayload = ( 28 28 method: string, 29 - url: string, 29 + htu: string, 30 30 nonce: string | undefined, 31 31 ath: string | undefined, 32 32 ) => { ··· 35 35 iat: Math.floor(Date.now() / 1_000), 36 36 jti: generateJti(), 37 37 htm: method, 38 - htu: url, 38 + htu: htu, 39 39 nonce: nonce, 40 40 ath: ath, 41 41 }; ··· 43 43 return toBase64Url(encoder.encode(JSON.stringify(payload))); 44 44 }; 45 45 46 - return async (method: string, url: string, nonce: string | undefined, ath: string | undefined) => { 47 - const payloadString = constructPayload(method, url, nonce, ath); 46 + return async (method: string, htu: string, nonce: string | undefined, ath: string | undefined) => { 47 + const payloadString = constructPayload(method, htu, nonce, ath); 48 48 49 49 const signed = await crypto.subtle.sign( 50 50 { name: 'ECDSA', hash: { name: 'SHA-256' } }, ··· 73 73 : undefined; 74 74 75 75 const { method, url } = request; 76 - const { origin } = new URL(url); 76 + const { origin, pathname } = new URL(url); 77 + 78 + const htu = origin + pathname; 77 79 78 80 // See if we have a pending promise for this origin, we'll await before 79 81 // proceeding with this request, next comment describes what the promise ··· 118 120 119 121 let nextNonce: string | null; 120 122 try { 121 - const initProof = await sign(method, url, initNonce, ath); 123 + const initProof = await sign(method, htu, initNonce, ath); 122 124 request.headers.set('dpop', initProof); 123 125 124 126 const initResponse = await fetch(request); ··· 164 166 // We got here because we were asked to retry the request (due to missing 165 167 // nonce value in the first request), let's do just that. 166 168 { 167 - const nextProof = await sign(method, url, nextNonce, ath); 169 + const nextProof = await sign(method, htu, nextNonce, ath); 168 170 const nextRequest = new Request(input, init); 169 171 nextRequest.headers.set('dpop', nextProof); 170 172