refactor progress
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {escapeInlineScriptValue} from '@fluxer/marketing/src/pages/InlineScriptEscaping';
|
||||
import {describe, expect, it} from 'vitest';
|
||||
|
||||
describe('escapeInlineScriptValue', () => {
|
||||
it('escapes backslash for safe embedding in single-quoted JS strings', () => {
|
||||
expect(escapeInlineScriptValue('path\\to\\file')).toBe('path\\\\to\\\\file');
|
||||
expect(escapeInlineScriptValue('\\\\')).toBe('\\\\\\\\');
|
||||
});
|
||||
|
||||
it('escapes newline for safe embedding in single-quoted JS strings', () => {
|
||||
expect(escapeInlineScriptValue('line1\nline2')).toBe('line1\\nline2');
|
||||
expect(escapeInlineScriptValue('\n')).toBe('\\n');
|
||||
});
|
||||
|
||||
it('escapes carriage return for safe embedding in single-quoted JS strings', () => {
|
||||
expect(escapeInlineScriptValue('a\rb')).toBe('a\\rb');
|
||||
expect(escapeInlineScriptValue('\r\n')).toBe('\\r\\n');
|
||||
});
|
||||
|
||||
it('escapes single quote to prevent string breakout', () => {
|
||||
expect(escapeInlineScriptValue("don't")).toBe("don\\'t");
|
||||
expect(escapeInlineScriptValue("it's")).toBe("it\\'s");
|
||||
expect(escapeInlineScriptValue("'")).toBe("\\'");
|
||||
});
|
||||
|
||||
it('escapes combined XSS-payload characters that could break out of JS strings', () => {
|
||||
const payload = "'; alert('xss'); //";
|
||||
expect(escapeInlineScriptValue(payload)).toBe("\\'; alert(\\'xss\\'); //");
|
||||
});
|
||||
|
||||
it('returns plain text unchanged when no special characters', () => {
|
||||
expect(escapeInlineScriptValue('Hello world')).toBe('Hello world');
|
||||
expect(escapeInlineScriptValue('Error: invalid amount')).toBe('Error: invalid amount');
|
||||
});
|
||||
});
|
||||
41
packages/marketing/src/__tests__/RedirectPathUtils.test.tsx
Normal file
41
packages/marketing/src/__tests__/RedirectPathUtils.test.tsx
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (C) 2026 Fluxer Contributors
|
||||
*
|
||||
* This file is part of Fluxer.
|
||||
*
|
||||
* Fluxer is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Fluxer is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with Fluxer. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {sanitizeInternalRedirectPath} from '@fluxer/marketing/src/RedirectPathUtils';
|
||||
import {describe, expect, test} from 'vitest';
|
||||
|
||||
describe('sanitizeInternalRedirectPath', () => {
|
||||
test('allows same-site relative paths', () => {
|
||||
expect(sanitizeInternalRedirectPath('/partners')).toBe('/partners');
|
||||
expect(sanitizeInternalRedirectPath('/download?channel=canary')).toBe('/download?channel=canary');
|
||||
expect(sanitizeInternalRedirectPath('/docs#faq')).toBe('/docs#faq');
|
||||
});
|
||||
|
||||
test('rejects absolute and protocol-relative external redirects', () => {
|
||||
expect(sanitizeInternalRedirectPath('https://evil.example/path')).toBe('/');
|
||||
expect(sanitizeInternalRedirectPath('//evil.example/path')).toBe('/');
|
||||
expect(sanitizeInternalRedirectPath('javascript:alert(1)')).toBe('/');
|
||||
});
|
||||
|
||||
test('normalises blank and relative values to internal paths', () => {
|
||||
expect(sanitizeInternalRedirectPath('')).toBe('/');
|
||||
expect(sanitizeInternalRedirectPath(' ')).toBe('/');
|
||||
expect(sanitizeInternalRedirectPath('download')).toBe('/download');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,11 @@
|
||||
# Terms of Service
|
||||
|
||||
## Table of contents
|
||||
|
||||
- [Welcome to Fluxer](#welcome-to-fluxer)
|
||||
|
||||
## Welcome to Fluxer {#welcome-to-fluxer}
|
||||
|
||||
we will automatically attempt to retry charging your payment method a reasonable number of times;
|
||||
|
||||
See [How to delete or disable your account](/help/delete-account) for details.
|
||||
Reference in New Issue
Block a user