23 lines
1.3 KiB
TypeScript
23 lines
1.3 KiB
TypeScript
import type { LocationQuery, LocationQueryRaw } from 'vue-router'
|
|
|
|
// Accept only this application's appointment route, never an arbitrary return URL.
|
|
export function appointmentReturnTarget(query: LocationQuery): string | null {
|
|
const value = query.appointmentReturn
|
|
if (typeof value !== 'string' || value.length > 12000) return null
|
|
try {
|
|
const target = new URL(value, 'https://appointment.invalid')
|
|
return target.origin === 'https://appointment.invalid' && target.pathname === '/appointment-calendar' && value.startsWith('/appointment-calendar?') && !target.hash ? `${target.pathname}${target.search}` : null
|
|
} catch { return null }
|
|
}
|
|
export function appointmentReturnQuery(query: LocationQuery): LocationQueryRaw {
|
|
const target = appointmentReturnTarget(query)
|
|
return target ? { appointmentReturn: target } : {}
|
|
}
|
|
export function appointmentExternalTarget(path: string, context: LocationQueryRaw) {
|
|
const target = new URL(path, 'https://appointment.invalid')
|
|
const params = new URLSearchParams()
|
|
for (const [key, value] of Object.entries(context)) if (value !== undefined && value !== null) params.set(key, String(value))
|
|
const query: Record<string, string> = { ...Object.fromEntries(target.searchParams), appointmentReturn: `/appointment-calendar?${params}` }
|
|
return { path: target.pathname, query }
|
|
}
|