// resources/js/composables/useUrlArgument.js // Utility for parsing URL argument format: /page-name--hHASHKEY (no colon) or /page-name--e:PAYLOAD /** * Parse URL path to extract page name, hashkey, and payload * @param {string} urlPath - The full URL path (e.g., "/edituser--h:HASHKEY") * @returns {object} - { slug, type, hashkey, payload } */ export function parseUrlArgument(urlPath) { if (!urlPath) return null; const result = { slug: '', // page name without arguments type: null, // 'hash' or 'payload' hashkey: null, payload: null }; try { // Extract the path from URL (remove query string) let path = urlPath; if (typeof window !== 'undefined') { const url = new URL(urlPath); path = url.pathname || urlPath; } // Remove leading slash and normalize path = path.replace(/^\/+/, ''); // Check for --h: (hashkey) or --e: (payload) patterns // Hash format: --h:BASE64 // Payload format: --e:BASE64 const hashMatch = path.match(/^(.*?)--h:(.*)$/); const payloadMatch = path.match(/^(.*?)--e:(.*)$/); if (hashMatch) { result.slug = hashMatch[1]; result.type = 'hash'; result.hashkey = decodeHashArgument('h:' + hashMatch[2]); return result; } if (payloadMatch) { result.slug = payloadMatch[1]; result.type = 'payload'; result.payload = decodePayloadArgument('e:' + payloadMatch[2]); return result; } // No hash/payload found - just return the slug result.slug = path; return result; } catch (e) { console.error('[parseUrlArgument] Error parsing URL argument:', e); return null; } } /** * Decode a hash argument from URL format */ export function decodeHashArgument(encodedValue) { if (!encodedValue) return null; // Handle both with and without 'h:' prefix let base64 = encodedValue; if (encodedValue.startsWith('h:')) { base64 = encodedValue.substring(2); } try { // First decode from base64 const decoded = atob(base64); // Then decode from URI component return decodeURIComponent(decoded); } catch (e) { // If decoding fails, it might be a raw hashkey that wasn't encoded return encodedValue; } } /** * Decode a payload argument from URL format */ export function decodePayloadArgument(encodedValue) { if (!encodedValue || !encodedValue.startsWith('e:')) return null; try { const base64 = encodedValue.substring(2); // First decodeURIComponent to convert percent-encoded chars back let decoded = decodeURIComponent(base64); // Then decode from base64 const decodedBytes = Uint8Array.from(atob(decoded), c => (c.charCodeAt(0) & 0xFF) ).map(c => String.fromCharCode(c)).join(''); return JSON.parse(decodedBytes); } catch (e) { console.error('[decodePayloadArgument] Error decoding payload:', e); return null; } } /** * Get URL argument type from path */ export function getUrlArgumentType(urlPath) { if (!urlPath) return null; const path = urlPath.replace(/^\/+/, ''); if (path.match(/^(.*?)--h:.*/)) { return 'hash'; } if (path.match(/^(.*?)--e:.*/)) { return 'payload'; } return null; } /** * Extract hashkey from URL path */ export function extractHashkeyFromUrl(urlPath) { if (!urlPath) return null; const path = urlPath.replace(/^\/+/, ''); const match = path.match(/^(.*?)--h:(.*)$/); if (match) { return decodeHashArgument('h:' + match[2]); } return null; } /** * Extract payload from URL path */ export function extractPayloadFromUrl(urlPath) { if (!urlPath) return null; const path = urlPath.replace(/^\/+/, ''); const match = path.match(/^(.*?)--e:(.*)$/); if (match) { return decodePayloadArgument(match[2]); } return null; }