Send hotlink access token hash on upload; keep secret client-side only.
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
import { createHash } from 'node:crypto';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { hashHotlinkAccessToken } from '@/utils/crypto/hashHotlinkAccessToken';
|
||||
|
||||
const hashAccessTokenLikeBackend = (accessToken: string): string =>
|
||||
createHash('sha256').update(accessToken, 'utf8').digest('hex');
|
||||
|
||||
const hotlinkAccessTokenHashVectors = [
|
||||
{
|
||||
accessToken: 'test-hotlink-access-token_base64url',
|
||||
accessTokenHash: '8defaf078afdd0ddabb77c73af4aa76ac78be24b6a6deffba2c6cfde43e20187'
|
||||
},
|
||||
{
|
||||
accessToken: 'ZWc6ttO-r2qssA_9gdWe6u14X2W0_j7xhRBSVQvfMKI',
|
||||
accessTokenHash: 'cdb772980ea3e958cf74b62b70a2f310eafbb9bf3d2302356b602b4830e89bc6'
|
||||
}
|
||||
] as const;
|
||||
|
||||
describe('hashHotlinkAccessToken', () => {
|
||||
it.each(hotlinkAccessTokenHashVectors)(
|
||||
'matches fixed SHA-256 hex for $accessToken',
|
||||
async ({ accessToken, accessTokenHash }) => {
|
||||
await expect(hashHotlinkAccessToken(accessToken)).resolves.toBe(accessTokenHash);
|
||||
}
|
||||
);
|
||||
|
||||
it('matches backend hashHotlinkAccessToken (Node crypto) for arbitrary tokens', async () => {
|
||||
const accessToken = 'another_base64url-style_secret-ABC123';
|
||||
|
||||
await expect(hashHotlinkAccessToken(accessToken)).resolves.toBe(hashAccessTokenLikeBackend(accessToken));
|
||||
});
|
||||
|
||||
it('returns 64 lowercase hex characters (SHA-256 digest)', async () => {
|
||||
const hash = await hashHotlinkAccessToken(hotlinkAccessTokenHashVectors[0].accessToken);
|
||||
|
||||
expect(hash).toMatch(/^[a-f0-9]{64}$/);
|
||||
});
|
||||
|
||||
it('changes when the access token string changes', async () => {
|
||||
const [first, second] = hotlinkAccessTokenHashVectors;
|
||||
|
||||
expect(first.accessTokenHash).not.toBe(second.accessTokenHash);
|
||||
});
|
||||
|
||||
it('hashes the UTF-8 string, not base64url-decoded bytes', async () => {
|
||||
const accessToken = 'AQ';
|
||||
|
||||
await expect(hashHotlinkAccessToken(accessToken)).resolves.toBe(hashAccessTokenLikeBackend(accessToken));
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user