| Name | Message | Date |
|---|---|---|
| 📁 ui | 10 hours ago | |
| 📄 api.ts | 10 hours ago | |
| 📄 auth.ts | 10 hours ago | |
| 📄 content.ts | 10 hours ago | |
| 📄 errors.ts | 10 hours ago | |
| 📄 hash.ts | 10 hours ago | |
| 📄 md5.ts | 10 hours ago | |
| 📄 selectors.ts | 10 hours ago | |
| 📄 titles.ts | 10 hours ago |
📄
src/hash.ts
import { md5 } from './md5';
/**
* The exact Accept header the reader app sends when fetching a PDF.
* It is part of the media CDN hash, so it must match byte for byte.
*/
export const PDF_ACCEPT =
'application/pdf, image/webp, image/jpeg, image/png, image/gif, image/svg';
/**
* The media CDN "hotlink" hash, computed by the reader app as
* md5("<Accept header>|<origin>|<client-authorize header, always empty>").
* Verified against real traffic (download.har): the PDF Accept header and the
* origin "https://etidning.vf.se" produce the h value seen in the wild.
*/
export function mediaHash(origin: string): string {
return md5(`${PDF_ACCEPT}|${origin}|`);
}
/** Appends the h parameter to a media URL. */
export function withMediaHash(url: string, origin: string): string {
const parsed = new URL(url, origin);
parsed.searchParams.set('h', mediaHash(origin));
return parsed.toString();
}