Files
bedolaga-cabinet/src/utils/safeRedirect.test.ts

37 lines
1.3 KiB
TypeScript

import { describe, expect, it } from 'vitest';
import { getSafeRedirectPath } from './safeRedirect';
describe('getSafeRedirectPath', () => {
it('returns / for empty values', () => {
expect(getSafeRedirectPath(null)).toBe('/');
expect(getSafeRedirectPath(undefined)).toBe('/');
expect(getSafeRedirectPath('')).toBe('/');
});
it('keeps plain absolute in-app paths', () => {
expect(getSafeRedirectPath('/')).toBe('/');
expect(getSafeRedirectPath('/dashboard')).toBe('/dashboard');
expect(getSafeRedirectPath('/sub/page?tab=devices&x=1')).toBe('/sub/page?tab=devices&x=1');
});
it('rejects protocol-relative and absolute URLs', () => {
expect(getSafeRedirectPath('//evil.com')).toBe('/');
expect(getSafeRedirectPath('https://evil.com/path')).toBe('/');
expect(getSafeRedirectPath('http://evil.com')).toBe('/');
});
it('rejects non-path schemes', () => {
expect(getSafeRedirectPath('javascript:alert(1)')).toBe('/');
expect(getSafeRedirectPath('data:text/html,x')).toBe('/');
});
it('rejects URL-encoded host smuggling', () => {
expect(getSafeRedirectPath('%2F%2Fevil.com')).toBe('/');
expect(getSafeRedirectPath('/redirect%3A%2F%2Fevil.com')).toBe('/');
});
it('rejects malformed percent-encoding instead of throwing', () => {
expect(getSafeRedirectPath('/%E0%A4%A')).toBe('/');
});
});