Signal-Desktop/ts/util/buildExpiration.ts

89 lines
2.3 KiB
TypeScript

// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { Environment, getEnvironment } from '../environment';
import type { LoggerType } from '../types/Logging';
import { isNotUpdatable } from './version';
import { isInPast } from './timestamp';
import { DAY } from './durations';
const NINETY_ONE_DAYS = 91 * DAY;
const THIRTY_ONE_DAYS = 31 * DAY;
const SIXTY_DAYS = 60 * DAY;
export type GetBuildExpirationTimestampOptionsType = Readonly<{
version: string;
packagedBuildExpiration: number;
remoteBuildExpiration: number | undefined;
autoDownloadUpdate: boolean;
logger: LoggerType;
}>;
export function getBuildExpirationTimestamp({
version,
packagedBuildExpiration,
remoteBuildExpiration,
autoDownloadUpdate,
logger,
}: GetBuildExpirationTimestampOptionsType): number {
const localBuildExpiration =
isNotUpdatable(version) || autoDownloadUpdate
? packagedBuildExpiration
: packagedBuildExpiration - SIXTY_DAYS;
// Log the expiration date in this selector because it invalidates only
// if one of the arguments changes.
let result: number;
let type: string;
if (remoteBuildExpiration && remoteBuildExpiration < localBuildExpiration) {
type = 'remote';
result = remoteBuildExpiration;
} else {
type = 'local';
result = localBuildExpiration;
}
logger.info(`Build expires (${type}): ${new Date(result).toISOString()}`);
return result;
}
export type HasBuildExpiredOptionsType = Readonly<{
buildExpirationTimestamp: number;
autoDownloadUpdate: boolean;
now: number;
logger: LoggerType;
}>;
export function hasBuildExpired({
buildExpirationTimestamp,
autoDownloadUpdate,
now,
logger,
}: HasBuildExpiredOptionsType): boolean {
if (
getEnvironment() !== Environment.PackagedApp &&
buildExpirationTimestamp === 0
) {
return false;
}
if (isInPast(buildExpirationTimestamp)) {
return true;
}
const safeExpirationMs = autoDownloadUpdate
? NINETY_ONE_DAYS
: THIRTY_ONE_DAYS;
const buildExpirationDuration = buildExpirationTimestamp - now;
const tooFarIntoFuture = buildExpirationDuration > safeExpirationMs;
if (tooFarIntoFuture) {
logger.error(
'Build expiration is set too far into the future',
buildExpirationTimestamp
);
}
return tooFarIntoFuture || isInPast(buildExpirationTimestamp);
}