66 lines
1.7 KiB
TypeScript
66 lines
1.7 KiB
TypeScript
/**
|
|
* isAllowedStackFilename unit tests (#1196).
|
|
*
|
|
* v1.0.34 locked stack writes to a hardcoded set of names (docker-compose.yml,
|
|
* compose.yml, .env) which broke users who name their compose files after
|
|
* the service (e.g. headscale.yml). v1.0.35 relaxes to any .yml / .yaml file
|
|
* plus the .env family.
|
|
*
|
|
* The regex is the only thing standing between the API and writing files
|
|
* with arbitrary extensions, so it gets a focused unit test rather than
|
|
* relying on integration coverage.
|
|
*/
|
|
import { describe, expect, test } from 'bun:test';
|
|
import { isAllowedStackFilename } from '../src/lib/server/stack-filename';
|
|
|
|
describe('isAllowedStackFilename', () => {
|
|
test.each([
|
|
// Conventional compose names
|
|
['docker-compose.yml'],
|
|
['docker-compose.yaml'],
|
|
['compose.yml'],
|
|
['compose.yaml'],
|
|
// Custom compose names per service (the #1196 case)
|
|
['headscale.yml'],
|
|
['nginx.yaml'],
|
|
['my-custom-thing.yml'],
|
|
// Env file family
|
|
['.env'],
|
|
['.env.local'],
|
|
['.env.production'],
|
|
['prod.env'],
|
|
['staging.env']
|
|
])('accepts %s', (filename: string) => {
|
|
expect(isAllowedStackFilename(filename)).toBe(true);
|
|
});
|
|
|
|
test.each([
|
|
// Shell / executable
|
|
['payload.sh'],
|
|
['evil.bash'],
|
|
// SSH key target
|
|
['authorized_keys'],
|
|
// Cron / systemd files
|
|
['crontab'],
|
|
['my.service'],
|
|
// Web / config files
|
|
['nginx.conf'],
|
|
['index.html'],
|
|
// Plain extensions not in our allowlist
|
|
['data.json'],
|
|
['readme.md'],
|
|
// No extension
|
|
['Caddyfile'],
|
|
// Empty / whitespace
|
|
[''],
|
|
[' '],
|
|
// Tricks: .yml in the middle, not at the end
|
|
['compose.yml.bak'],
|
|
// .env in the middle
|
|
['environment'],
|
|
['notenv']
|
|
])('rejects %s', (filename: string) => {
|
|
expect(isAllowedStackFilename(filename)).toBe(false);
|
|
});
|
|
});
|