feat(app-update): add in-app update flow with native e2e coverage

This commit is contained in:
Tommaso Casaburi
2026-03-19 20:19:48 +08:00
parent bc870ae438
commit a2286aa68e
61 changed files with 1900 additions and 249 deletions
+36
View File
@@ -0,0 +1,36 @@
const DEFAULT_RELEASE_API_URL = 'https://api.github.com/repos/bitsocialnet/5chan/releases/latest';
const DEFAULT_RELEASES_BASE_URL = 'https://github.com/bitsocialnet/5chan/releases/tag/';
const parseConfiguredHosts = (value: string | undefined): Set<string> =>
new Set(
`${value || ''}`
.split(',')
.map((host) => host.trim().toLowerCase())
.filter(Boolean),
);
const configuredDownloadHosts = parseConfiguredHosts(import.meta.env.VITE_APP_UPDATE_ALLOWED_DOWNLOAD_HOSTS);
const getReleaseApiUrl = (): string => {
const configuredUrl = import.meta.env.VITE_APP_UPDATE_RELEASE_API_URL;
return typeof configuredUrl === 'string' && configuredUrl.trim().length > 0 ? configuredUrl.trim() : DEFAULT_RELEASE_API_URL;
};
const getDefaultReleaseUrl = (version: string): string => `${DEFAULT_RELEASES_BASE_URL}v${version.trim().replace(/^v/i, '').split('-')[0]}`;
const isAllowedDownloadUrl = (url: string): boolean => {
try {
const parsedUrl = new URL(url);
const hostname = parsedUrl.hostname.toLowerCase();
if (parsedUrl.protocol === 'https:' && hostname === 'github.com') {
return true;
}
return configuredDownloadHosts.has(hostname) && (parsedUrl.protocol === 'https:' || parsedUrl.protocol === 'http:');
} catch {
return false;
}
};
export { getDefaultReleaseUrl, getReleaseApiUrl, isAllowedDownloadUrl };