Merge pull request #2205 from Bilb/updater-reword

Updater rework and bump to 1.8.3
pull/2225/head
Audric Ackermann 3 years ago committed by GitHub
commit e7802287fc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -63,9 +63,7 @@ jobs:
- name: Lint Files
if: runner.os != 'Windows'
run: |
yarn format-full
yarn eslint
yarn tslint
yarn lint-full
- name: Make linux use en_US locale
if: runner.os == 'Linux'

@ -127,7 +127,7 @@ module.exports = grunt => {
});
function updateLocalConfig(update) {
const environment = process.env.SIGNAL_ENV || 'development';
const environment = process.env.SIGNAL_ENV || 'production';
const configPath = `config/local-${environment}.json`;
let localConfig;
try {

@ -4,7 +4,6 @@ const process = require('process');
const { app } = require('electron');
const { start } = require('./base_config');
const config = require('./config');
let storageProfile;
@ -16,10 +15,7 @@ const isValidInstance = typeof instance === 'string' && instance.length > 0;
const isProduction = environment === 'production' && !isValidInstance;
// Use seperate data directories for each different environment and app instances
// We should prioritise config values first
if (config.has(storageProfile)) {
storageProfile = config.get('storageProfile');
} else if (!isProduction) {
if (!isProduction) {
storageProfile = environment;
if (isValidInstance) {
storageProfile = storageProfile.concat(`-${instance}`);

@ -1,21 +1,4 @@
{
"serverUrl": "random.snode",
"localUrl": "localhost.loki",
"cdnUrl": "random.snode",
"contentProxyUrl": "",
"seedNodeList": [
{
"url": "https://storage.seed1.loki.network:4433/"
},
{
"url": "https://storage.seed3.loki.network:4433/"
},
{
"url": "https://public.loki.foundation:4433/"
}
],
"updatesEnabled": false,
"openDevTools": false,
"commitHash": "",
"import": false
}

@ -1,8 +0,0 @@
{
"seedNodeList": [
{
"url": "http://public.loki.foundation:38157/"
}
],
"openDevTools": false
}

@ -1,4 +0,0 @@
{
"openDevTools": false,
"updatesEnabled": false
}

@ -1,4 +0,0 @@
{
"openDevTools": true,
"updatesEnabled": false
}

@ -1,4 +0,0 @@
{
"openDevTools": true,
"updatesEnabled": false
}

@ -1,3 +1 @@
{
"updatesEnabled": true
}
{}

@ -1,8 +0,0 @@
{
"seedNodeList": [
{
"url": "http://localhost:22129/"
}
],
"openDevTools": true
}

@ -1,4 +0,0 @@
{
"storageProfile": "test",
"openDevTools": false
}

@ -1,4 +0,0 @@
{
"storageProfile": "test",
"openDevTools": false
}

@ -386,7 +386,7 @@
}
let connectCount = 0;
async function connect(firstRun) {
async function connect() {
window.log.info('connect');
// Bootstrap our online/offline detection, only the first time we connect
@ -400,10 +400,6 @@
return;
}
if (firstRun) {
window.readyForUpdates();
}
if (!Whisper.Registration.everDone()) {
return;
}

@ -76,6 +76,8 @@ const { installPermissionsHandler } = require('./app/permissions');
let appStartInitialSpellcheckSetting = true;
let latestDesktopRelease;
async function getSpellCheckSetting() {
const json = await sql.getItemById('spell-check');
// Default to `true` if setting doesn't exist yet
@ -155,17 +157,11 @@ function prepareURL(pathSegments, moreKeys) {
locale: locale.name,
version: app.getVersion(),
commitHash: config.get('commitHash'),
serverUrl: config.get('serverUrl'),
localUrl: config.get('localUrl'),
cdnUrl: config.get('cdnUrl'),
// one day explain why we need to do this - neuroscr
seedNodeList: JSON.stringify(config.get('seedNodeList')),
environment: config.environment,
node_version: process.versions.node,
hostname: os.hostname(),
appInstance: process.env.NODE_APP_INSTANCE,
proxyUrl: process.env.HTTPS_PROXY || process.env.https_proxy,
contentProxyUrl: config.contentProxyUrl,
appStartInitialSpellcheckSetting,
...moreKeys,
},
@ -344,7 +340,7 @@ async function createWindow() {
mainWindow.loadURL(prepareURL([__dirname, 'background.html']));
if (config.get('openDevTools')) {
if ((process.env.NODE_APP_INSTANCE || '').startsWith('devprod')) {
// Open the DevTools.
mainWindow.webContents.openDevTools({
mode: 'bottom',
@ -398,31 +394,30 @@ async function createWindow() {
// when you should delete the corresponding element.
mainWindow = null;
});
mainWindow.getLatestDesktopRelease = () => latestDesktopRelease;
}
ipc.on('show-window', () => {
showWindow();
});
ipc.on('set-release-from-file-server', (_event, releaseGotFromFileServer) => {
latestDesktopRelease = releaseGotFromFileServer;
});
let isReadyForUpdates = false;
async function readyForUpdates() {
console.log('[updater] isReadyForUpdates', isReadyForUpdates);
if (isReadyForUpdates) {
return;
}
isReadyForUpdates = true;
// disable for now
/*
// First, install requested sticker pack
const incomingUrl = getIncomingUrl(process.argv);
if (incomingUrl) {
handleSgnlLink(incomingUrl);
}
*/
// Second, start checking for app updates
try {
// if the user disabled auto updates, this will actually not start the updater
await updater.start(getMainWindow, userConfig, locale.messages, logger);
} catch (error) {
const log = logger || console;
@ -703,9 +698,6 @@ async function showMainWindow(sqlKey, passwordAttempt = false) {
}
setupMenu();
// Check updates
readyForUpdates();
}
function setupMenu(options) {

@ -2,7 +2,7 @@
"name": "session-desktop",
"productName": "Session",
"description": "Private messaging from your desktop",
"version": "1.7.8",
"version": "1.8.3",
"license": "GPL-3.0",
"author": {
"name": "Oxen Labs",
@ -15,37 +15,29 @@
"main": "main.js",
"scripts": {
"postinstall": "electron-builder install-app-deps && rimraf node_modules/dtrace-provider",
"start": "cross-env NODE_APP_INSTANCE=$MULTI electron .",
"start-prod": "cross-env NODE_ENV=production NODE_APP_INSTANCE=devprod$MULTI electron .",
"grunt": "yarn clean-transpile && grunt",
"grunt:dev": "yarn clean-transpile; yarn grunt dev --force",
"grunt": "yarn clean-transpile && grunt",
"generate": "yarn grunt --force",
"build-release": "run-script-os",
"build-release-non-linux": "cross-env SIGNAL_ENV=production electron-builder --config.extraMetadata.environment=production --publish=never --config.directories.output=release",
"build-release-non-linux": "yarn generate && cross-env SIGNAL_ENV=production electron-builder --config.extraMetadata.environment=production --publish=never --config.directories.output=release",
"build-release:win32": "yarn build-release-non-linux",
"build-release:macos": "yarn build-release-non-linux",
"build-release:linux": "yarn sedtoDeb; yarn build-release-non-linux && yarn sedtoAppImage && yarn build-release-non-linux && yarn sedtoDeb",
"build-release-publish": "run-script-os",
"build-release-publish-non-linux": "$(yarn bin)/electron-builder --config.extraMetadata.environment=$SIGNAL_ENV --publish=always",
"build-release-publish-non-linux": "cross-env SIGNAL_ENV=production $(yarn bin)/electron-builder --config.extraMetadata.environment=$SIGNAL_ENV --publish=always",
"build-release-publish:win32": "yarn build-release-publish-non-linux",
"build-release-publish:macos": "yarn build-release-publish-non-linux",
"build-release-publish:linux": "yarn sedtoDeb; yarn build-release-publish-non-linux && yarn sedtoAppImage && yarn build-release-publish-non-linux && yarn sedtoDeb",
"build-module-protobuf": "pbjs --target static-module --wrap commonjs --out ts/protobuf/compiled.js protos/*.proto && pbts --out ts/protobuf/compiled.d.ts ts/protobuf/compiled.js --force-long",
"clean-module-protobuf": "rimraf ts/protobuf/compiled.d.ts ts/protobuf/compiled.js",
"build-protobuf": "yarn build-module-protobuf",
"clean-protobuf": "yarn clean-module-protobuf",
"test": "yarn test-node",
"test-node": "mocha --recursive --exit --timeout 10000 \"./ts/test/**/*_test.js\" ",
"eslint-full": "eslint .",
"lint-full": "yarn format-full && yarn lint-files-full",
"lint-files-full": "yarn eslint-full && yarn tslint",
"tslint": "tslint --format stylish --project .",
"appImage": "yarn sedtoAppImage; yarn build-release-non-linux; yarn sedtoDeb",
"build-protobuf": "pbjs --target static-module --wrap commonjs --out ts/protobuf/compiled.js protos/*.proto && pbts --out ts/protobuf/compiled.d.ts ts/protobuf/compiled.js --force-long",
"test": "mocha --recursive --exit --timeout 10000 \"./ts/test/**/*_test.js\" ",
"lint-full": "yarn format-full && eslint . && tslint --format stylish --project .",
"format-full": "prettier --list-different --write \"*.{css,js,json,scss,ts,tsx}\" \"./**/*.{css,js,json,scss,ts,tsx}\"",
"transpile": "tsc --incremental",
"transpile:watch": "yarn grunt --force; tsc -w",
"integration-test": "mocha --recursive --exit --timeout 30000 \"./ts/test-integration/**/*.test.js\" \"./ts/test/*.test.js\"",
"transpile": "tsc",
"transpile:watch": "yarn grunt --force; tsc -w",
"integration-test": "npx playwright test",
"clean-transpile": "rimraf 'ts/**/*.js' 'ts/*.js' 'ts/*.js.map' 'ts/**/*.js.map' && rimraf tsconfig.tsbuildinfo;",
"ready": "yarn clean-transpile; yarn grunt && yarn lint-full && yarn test",
"ready": "yarn grunt && yarn lint-full && yarn test",
"sedtoAppImage": "sed -i 's/\"target\": \\[\"deb\", \"rpm\", \"freebsd\"\\]/\"target\": \"AppImage\"/g' package.json",
"sedtoDeb": "sed -i 's/\"target\": \"AppImage\"/\"target\": \\[\"deb\", \"rpm\", \"freebsd\"\\]/g' package.json"
},
@ -65,7 +57,6 @@
"color": "^3.1.2",
"config": "1.28.1",
"country-code-lookup": "^0.0.19",
"cross-env": "^6.0.3",
"curve25519-js": "^0.0.4",
"dompurify": "^2.0.7",
"electron-is-dev": "^1.1.0",
@ -162,6 +153,7 @@
"chai": "^4.3.4",
"chai-as-promised": "^7.1.1",
"chai-bytes": "^0.1.2",
"cross-env": "^6.0.3",
"electron": "^13.6.2",
"electron-builder": "22.8.0",
"electron-notarize": "^0.2.0",

@ -31,7 +31,7 @@ window.getNodeVersion = () => config.node_version;
window.sessionFeatureFlags = {
useOnionRequests: true,
useCallMessage: false,
useCallMessage: true,
};
window.versionInfo = {
@ -211,7 +211,17 @@ window.ReactDOM = require('react-dom');
window.clipboard = clipboard;
window.getSeedNodeList = () => JSON.parse(config.seedNodeList);
window.getSeedNodeList = () => [
{
url: 'https://storage.seed1.loki.network:4433/',
},
{
url: 'https://storage.seed3.loki.network:4433/',
},
{
url: 'https://public.loki.foundation:4433/',
},
];
const { locale: localFromEnv } = config;
window.i18n = i18n.setup(localFromEnv, localeMessages);

@ -122,12 +122,12 @@ export class SessionRecording extends React.Component<Props, State> {
return (
<div role="main" className="session-recording" tabIndex={0} onKeyDown={this.onKeyDown}>
<div className="session-recording--actions">
<StyledFlexWrapper marginHorizontal={Constants.UI.SPACING.marginXs}>
<StyledFlexWrapper marginHorizontal="5px">
{isRecording && (
<SessionIconButton
iconType="stop"
iconSize="medium"
iconColor={Constants.UI.COLORS.DANGER_ALT}
iconColor={'#FF4538'}
onClick={actionPauseFn}
/>
)}

@ -34,7 +34,7 @@ import { conversationChanged, conversationRemoved } from '../../state/ducks/conv
import { editProfileModal, onionPathModal } from '../../state/ducks/modalDialog';
import { uploadOurAvatar } from '../../interactions/conversationInteractions';
import { ModalContainer } from '../dialog/ModalContainer';
import { debounce } from 'lodash';
import { debounce, isEmpty, isString } from 'lodash';
// tslint:disable-next-line: no-import-side-effect no-submodule-imports
@ -51,6 +51,8 @@ import { IncomingCallDialog } from '../calling/IncomingCallDialog';
import { SessionIconButton } from '../icon';
import { SessionToastContainer } from '../SessionToastContainer';
import { LeftPaneSectionContainer } from './LeftPaneSectionContainer';
import { getLatestDesktopReleaseFileToFsV2 } from '../../session/apis/file_server_api/FileServerApiV2';
import { ipcRenderer } from 'electron';
const Section = (props: { type: SectionType }) => {
const ourNumber = useSelector(getOurNumber);
@ -162,7 +164,12 @@ const Section = (props: { type: SectionType }) => {
}
};
const cleanUpMediasInterval = DURATION.MINUTES * 30;
const cleanUpMediasInterval = DURATION.MINUTES * 60;
// every 10 minutes we fetch from the fileserver to check for a new release
// * if there is none, no request to github are made.
// * if there is a version on the fileserver more recent than our current, we fetch github to get the UpdateInfos and trigger an update as usual (asking user via dialog)
const fetchReleaseFromFileServerInterval = 1000 * 60; // try to fetch the latest release from the fileserver every minute
const setupTheme = () => {
const theme = window.Events.getThemeSetting();
@ -265,6 +272,22 @@ const CallContainer = () => {
);
};
async function fetchReleaseFromFSAndUpdateMain() {
try {
window.log.warn('[updater] about to fetchReleaseFromFSAndUpdateMain');
const latest = await getLatestDesktopReleaseFileToFsV2();
window.log.warn('[updater] fetched latest release from fsv2: ', latest);
if (isString(latest) && !isEmpty(latest)) {
ipcRenderer.send('set-release-from-file-server', latest);
window.readyForUpdates();
}
} catch (e) {
window.log.warn(e);
}
}
/**
* ActionsPanel is the far left banner (not the left pane).
* The panel with buttons to switch between the message/contact/settings/theme views
@ -289,6 +312,10 @@ export const ActionsPanel = () => {
useInterval(cleanUpOldDecryptedMedias, startCleanUpMedia ? cleanUpMediasInterval : null);
useInterval(() => {
void fetchReleaseFromFSAndUpdateMain();
}, fetchReleaseFromFileServerInterval);
if (!ourPrimaryConversation) {
window?.log?.warn('ActionsPanel: ourPrimaryConversation is not set');
return null;

@ -50,28 +50,8 @@ export const VALIDATION = {
};
export const UI = {
// Pixels (scroll) from the top of the top of message container
// at which more messages should be loaded
MESSAGE_CONTAINER_BUFFER_OFFSET_PX: 1,
COLORS: {
// COMMON
WHITE: '#FFFFFF',
WHITE_PALE: '#AFAFAF',
GREEN: '#00F782',
// CAUTION
WARNING: '#FFC02E',
// SEMANTIC COLORS
DANGER: '#FF453A',
DANGER_ALT: '#FF4538',
},
SPACING: {
marginXs: '5px',
marginSm: '10px',
marginMd: '15px',
marginLg: '20px',
},
};

@ -130,7 +130,14 @@ export async function TEST_sendMessageToSnode(
const data64 = window.dcodeIO.ByteBuffer.wrap(data).toString('base64');
const swarm = await getSwarmFor(pubKey);
window?.log?.debug('Sending envelope with timestamp: ', timestamp, ' to ', ed25519Str(pubKey));
window?.log?.debug(
'Sending envelope with timestamp: ',
timestamp,
' to ',
ed25519Str(pubKey),
' size base64:',
data64.length
);
// send parameters
const params = {
pubKey,

@ -1,23 +1,24 @@
import { get as getFromConfig } from 'config';
import { BrowserWindow } from 'electron';
import { start as startUpdater, stop as stopUpdater } from './updater';
import { LoggerType, MessagesType } from './common';
import { UserConfig } from '../../app/user_config';
let initialized = false;
let config: UserConfig;
let localUserConfig: UserConfig;
export async function start(
getMainWindow: () => BrowserWindow,
userConfig: UserConfig,
messages?: MessagesType,
logger?: LoggerType
messages: MessagesType,
logger: LoggerType
) {
if (initialized) {
throw new Error('updater/start: Updates have already been initialized!');
}
initialized = true;
config = userConfig;
if (!userConfig) {
throw new Error('updater/start: userConfig is needed!');
}
if (!messages) {
throw new Error('updater/start: Must provide messages!');
@ -25,15 +26,10 @@ export async function start(
if (!logger) {
throw new Error('updater/start: Must provide logger!');
}
initialized = true;
localUserConfig = userConfig; // reused below
if (autoUpdateDisabled()) {
/*
If you really want to enable auto-updating in dev mode
You need to create a dev-app-update.yml file.
A sample can be found in dev-app-update.yml.sample.
After that you can change `updatesEnabled` to `true` in the default config.
*/
logger.info('updater/start: Updates disabled - not starting new version checks');
return;
@ -51,12 +47,11 @@ export function stop() {
function autoUpdateDisabled() {
// We need to ensure that if auto update is not present in the user config then we assume it is on by default
const userSetting = config.get('autoUpdate');
const userSetting = localUserConfig.get('autoUpdate');
const autoUpdate = typeof userSetting !== 'boolean' || userSetting;
return (
process.mas || // From Electron: Mac App Store build
!getFromConfig('updatesEnabled') || // Hard coded config
// tslint:disable-next-line: no-backbone-get-set-outside-model
!autoUpdate // User setting
);

@ -19,10 +19,6 @@ let downloadIgnored = false;
let interval: NodeJS.Timeout | undefined;
let stopped = false;
const SECOND = 1000;
const MINUTE = SECOND * 60;
const INTERVAL = MINUTE * 30;
export async function start(
getMainWindow: () => BrowserWindow,
messages: MessagesType,
@ -45,7 +41,7 @@ export async function start(
} catch (error) {
logger.error('auto-update: error:', getPrintableError(error));
}
}, INTERVAL);
}, 1000 * 60 * 10); // trigger and try to update every 10 minutes to let the file gets downloaded if we are updating
stopped = false;
await checkForUpdates(getMainWindow, messages, logger);
@ -64,38 +60,70 @@ async function checkForUpdates(
messages: MessagesType,
logger: LoggerType
) {
logger.info('[updater] checkForUpdates');
if (stopped || isUpdating || downloadIgnored) {
return;
}
const canUpdate = await canAutoUpdate();
logger.info('[updater] canUpdate', canUpdate);
if (!canUpdate) {
logger.info('checkForUpdates canAutoUpdate false');
return;
}
logger.info('auto-update: checking for update...');
logger.info('[updater] checkForUpdates...');
isUpdating = true;
try {
// Get the update using electron-updater
const latestVersionFromFsFromRenderer = getMainWindow()
? ((getMainWindow() as any).getLatestDesktopRelease() as string | undefined)
: undefined;
logger.info('[updater] latestVersionFromFsFromRenderer', latestVersionFromFsFromRenderer);
if (!latestVersionFromFsFromRenderer || !latestVersionFromFsFromRenderer?.length) {
logger.info(
'[updater] testVersionFromFsFromRenderer was not updated yet by renderer. Skipping update check'
);
return;
}
const currentVersion = autoUpdater.currentVersion.toString();
const isMoreRecent = isVersionGreaterThan(latestVersionFromFsFromRenderer, currentVersion);
logger.info('[updater] checkForUpdates isMoreRecent', isMoreRecent);
if (!isMoreRecent) {
logger.info(
`Fileserver has no update so we are not looking for an update from github current:${currentVersion} fromFileServer:${latestVersionFromFsFromRenderer}`
);
return;
}
// Get the update using electron-updater, this fetches from github
const result = await autoUpdater.checkForUpdates();
logger.info('[updater] checkForUpdates got github response back ');
if (!result.updateInfo) {
logger.info('auto-update: no update info received');
logger.info('[updater] no update info received');
return;
}
try {
const hasUpdate = isUpdateAvailable(result.updateInfo);
logger.info('[updater] hasUpdate:', hasUpdate);
if (!hasUpdate) {
logger.info('auto-update: no update available');
logger.info('[updater] no update available');
return;
}
logger.info('auto-update: showing download dialog...');
logger.info('[updater] showing download dialog...');
const shouldDownload = await showDownloadUpdateDialog(getMainWindow(), messages);
logger.info('[updater] shouldDownload:', shouldDownload);
if (!shouldDownload) {
downloadIgnored = true;
@ -109,13 +137,13 @@ async function checkForUpdates(
}
// Update downloaded successfully, we should ask the user to update
logger.info('auto-update: showing update dialog...');
logger.info('[updater] showing update dialog...');
const shouldUpdate = await showUpdateDialog(getMainWindow(), messages);
if (!shouldUpdate) {
return;
}
logger.info('auto-update: calling quitAndInstall...');
logger.info('[updater] calling quitAndInstall...');
markShouldQuit();
autoUpdater.quitAndInstall();
} finally {

1
ts/window.d.ts vendored

@ -59,6 +59,7 @@ declare global {
userConfig: any;
versionInfo: any;
getConversations: () => ConversationCollection;
readyForUpdates: () => void;
MediaRecorder: any;
contextMenuShown: boolean;

Loading…
Cancel
Save