feat(validation): relax Instagram URL validation to support all content types
- Create validateInstagramUrl utility using URL constructor - Replace regex-based validation with hostname and protocol checks - Support posts, reels, IGTV, and URLs with query parameters - Add comprehensive unit tests (22 tests, all passing) - Add integration tests for new URL formats - Update API documentation with supported URL formats Closes: #RelaxInstagramUrlValidation
This commit is contained in:
79
src/lib/server/validation/instagram-url.ts
Normal file
79
src/lib/server/validation/instagram-url.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
/**
|
||||
* Instagram URL Validation Utility
|
||||
*
|
||||
* Validates that a URL is from Instagram's domain and uses HTTPS.
|
||||
* Accepts all Instagram URL formats (posts, reels, IGTV, etc.).
|
||||
*/
|
||||
|
||||
export interface ValidationResult {
|
||||
valid: boolean;
|
||||
error?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate Instagram URL
|
||||
*
|
||||
* Accepts:
|
||||
* - https://instagram.com/p/{post-id}
|
||||
* - https://www.instagram.com/p/{post-id}
|
||||
* - https://instagram.com/reel/{reel-id}
|
||||
* - https://instagram.com/tv/{tv-id}
|
||||
* - Any Instagram URL with query parameters
|
||||
*
|
||||
* Rejects:
|
||||
* - Non-HTTPS URLs (http://)
|
||||
* - Non-Instagram domains
|
||||
* - Invalid URL format
|
||||
* - Subdomains other than www
|
||||
*
|
||||
* @param url - The URL to validate
|
||||
* @returns Validation result with valid flag and optional error message
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const result = validateInstagramUrl('https://instagram.com/reel/ABC123?utm_source=share');
|
||||
* if (!result.valid) {
|
||||
* console.error(result.error);
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export function validateInstagramUrl(url: string): ValidationResult {
|
||||
// Validate URL is a string
|
||||
if (typeof url !== 'string' || url.trim() === '') {
|
||||
return {
|
||||
valid: false,
|
||||
error: 'URL must be a non-empty string'
|
||||
};
|
||||
}
|
||||
|
||||
// Parse URL
|
||||
let urlObj: URL;
|
||||
try {
|
||||
urlObj = new URL(url);
|
||||
} catch (e) {
|
||||
return {
|
||||
valid: false,
|
||||
error: 'Invalid URL format'
|
||||
};
|
||||
}
|
||||
|
||||
// Validate protocol (must be HTTPS)
|
||||
if (urlObj.protocol !== 'https:') {
|
||||
return {
|
||||
valid: false,
|
||||
error: 'Instagram URL must use HTTPS protocol'
|
||||
};
|
||||
}
|
||||
|
||||
// Validate hostname (must be instagram.com or www.instagram.com)
|
||||
const validHostnames = ['instagram.com', 'www.instagram.com'];
|
||||
if (!validHostnames.includes(urlObj.hostname)) {
|
||||
return {
|
||||
valid: false,
|
||||
error: 'URL must be from instagram.com domain'
|
||||
};
|
||||
}
|
||||
|
||||
// Valid Instagram URL
|
||||
return { valid: true };
|
||||
}
|
||||
Reference in New Issue
Block a user