refactor: use combined shareId (locationId + checksum) in URL
Changes:
- Add generateShareId() and extractShareId() helpers
- Share URLs now use single parameter: /share/location/{shareId}
- shareId = locationId (24 chars) + checksum (16 chars) = 40 chars total
- Update validateShareAccess() to extract locationId from shareId
- Update uploadProofOfPayment() to accept combined shareId
- Update LocationViewPage to validate and extract locationId from shareId
Benefits:
- Simpler URL structure (one parameter instead of two)
- Checksum extraction by length (deterministic, no parsing needed)
- Same security properties (HMAC-SHA256 validation)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,10 @@
|
||||
import crypto from 'crypto';
|
||||
|
||||
/**
|
||||
* Checksum length in hex characters (16 chars = 64 bits of entropy)
|
||||
*/
|
||||
export const CHECKSUM_LENGTH = 16;
|
||||
|
||||
/**
|
||||
* Generate share link checksum for location
|
||||
* Uses HMAC-SHA256 for cryptographic integrity
|
||||
@@ -17,7 +22,7 @@ export function generateShareChecksum(locationId: string): string {
|
||||
.createHmac('sha256', secret)
|
||||
.update(locationId)
|
||||
.digest('hex')
|
||||
.substring(0, 16); // 64 bits of entropy (sufficient for share links)
|
||||
.substring(0, CHECKSUM_LENGTH);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -50,3 +55,32 @@ export function validateShareChecksum(
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate combined location ID with checksum appended
|
||||
* @param locationId - The MongoDB location ID (24 chars)
|
||||
* @returns Combined ID: locationId + checksum (40 chars total)
|
||||
*/
|
||||
export function generateShareId(locationId: string): string {
|
||||
const checksum = generateShareChecksum(locationId);
|
||||
return locationId + checksum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract location ID and checksum from combined share ID
|
||||
* @param shareId - Combined ID (locationId + checksum)
|
||||
* @returns Object with locationId and checksum, or null if invalid format
|
||||
*/
|
||||
export function extractShareId(shareId: string): { locationId: string; checksum: string } | null {
|
||||
// MongoDB ObjectID is 24 chars, checksum is 16 chars = 40 total
|
||||
const expectedLength = 24 + CHECKSUM_LENGTH;
|
||||
|
||||
if (shareId.length !== expectedLength) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const locationId = shareId.substring(0, 24);
|
||||
const checksum = shareId.substring(24);
|
||||
|
||||
return { locationId, checksum };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user