maestro/src/engine/browser-session-expiry.ts
2026-06-03 05:08:00 +00:00

41 lines
1.3 KiB
TypeScript

export interface AuthCheckProfile {
loggedInSelector: string | null;
loginUrlPatterns: string[];
}
export interface AuthCheckInput {
profile: AuthCheckProfile;
finalUrl: string;
statusCode: number;
loggedInSelectorPresent: boolean;
}
export type AuthExpiry = { expired: false } | { expired: true; reason: string };
function urlMatches(url: string, glob: string): boolean {
// Minimal glob: '**' = '.*', '*' = '[^/]*'
// Use a sentinel for '**' so the second '*' substitution doesn't clobber the '.*'.
const DOUBLE = '\x00DOUBLE\x00';
const escaped = glob
.replace(/\*\*/g, DOUBLE)
.replace(/[.+?^${}()|[\]\\]/g, '\\$&')
.replace(/\*/g, '[^/]*')
.split(DOUBLE).join('.*');
return new RegExp('^' + escaped + '$').test(url);
}
export function detectAuthExpiry(input: AuthCheckInput): AuthExpiry {
if (input.statusCode === 401 || input.statusCode === 403) {
return { expired: true, reason: `HTTP ${input.statusCode}` };
}
for (const pattern of input.profile.loginUrlPatterns) {
if (urlMatches(input.finalUrl, pattern)) {
return { expired: true, reason: 'redirected to login URL' };
}
}
if (input.profile.loggedInSelector && !input.loggedInSelectorPresent) {
return { expired: true, reason: 'logged-in selector not found' };
}
return { expired: false };
}