Skip to content

Commit

Permalink
Merge pull request #512 from internxt/fix/2-1-0-release
Browse files Browse the repository at this point in the history
Release 2-1-2
  • Loading branch information
ArceDanielShok authored Sep 9, 2024
2 parents 9ab2305 + 3a47024 commit 706f357
Show file tree
Hide file tree
Showing 46 changed files with 330 additions and 153 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "internxt-drive",
"version": "2.1.1",
"version": "2.1.2",
"author": "Internxt <[email protected]>",
"description": "Internxt Drive client UI",
"license": "AGPL-3.0",
Expand Down
2 changes: 1 addition & 1 deletion release/app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "internxt-drive",
"version": "2.1.1",
"version": "2.1.2",
"description": "Internxt Drive client UI",
"main": "./dist/main/main.js",
"author": "Internxt <[email protected]>",
Expand Down
11 changes: 8 additions & 3 deletions src/apps/main/auth/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ import Logger from 'electron-log';
import { AccessResponse } from '../../renderer/pages/Login/service';
import { applicationOpened } from '../analytics/service';
import eventBus from '../event-bus';
import { setupRootFolder } from '../virtual-root-folder/service';
import {
clearRootVirtualDrive,
setupRootFolder,
} from '../virtual-root-folder/service';
import { getWidget } from '../windows/widget';
import { createTokenSchedule } from './refresh-token';
import { checkUserData, createTokenSchedule } from './refresh-token';
import {
canHisConfigBeRestored,
encryptToken,
Expand Down Expand Up @@ -49,6 +52,7 @@ ipcMain.handle('get-token', () => {

export function onUserUnauthorized() {
eventBus.emit('USER_WAS_UNAUTHORIZED');
eventBus.emit('USER_LOGGED_OUT');

logout();
Logger.info('[AUTH] User has been logged out because it was unauthorized');
Expand All @@ -62,6 +66,7 @@ ipcMain.on('user-logged-in', async (_, data: AccessResponse) => {
if (!canHisConfigBeRestored(data.user.uuid)) {
await setupRootFolder();
}
await await clearRootVirtualDrive();

setIsLoggedIn(true);
eventBus.emit('USER_LOGGED_IN');
Expand All @@ -79,7 +84,7 @@ eventBus.on('APP_IS_READY', async () => {
if (!isLoggedIn) {
return;
}

await checkUserData();
encryptToken();
applicationOpened();
await createTokenSchedule();
Expand Down
43 changes: 39 additions & 4 deletions src/apps/main/auth/refresh-token.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
import Logger from 'electron-log';

import { getClient } from '../../shared/HttpClient/main-process-client';
import { getNewTokenClient } from '../../shared/HttpClient/main-process-client';
import { TokenScheduler } from '../token-scheduler/TokenScheduler';
import { onUserUnauthorized } from './handlers';
import {
getUser,
obtainTokens as obtainStoredTokens,
setUser,
updateCredentials,
} from './service';
import axios from 'axios';

const authorizedClient = getClient();
const newAuthorizedClient = getNewTokenClient();

async function obtainTokens() {
try {
Logger.debug('[TOKEN] Obtaining new tokens');
const res = await authorizedClient.get(
`${process.env.API_URL}/user/refresh`
const res = await newAuthorizedClient.get(
`${process.env.NEW_DRIVE_URL}/drive/users/refresh`
);

return res.data;
Expand All @@ -34,6 +37,7 @@ async function refreshToken() {

updateCredentials(token, newToken);

Logger.debug('[TOKEN] Refreshed tokens', token, newToken);
return [token, newToken];
}

Expand All @@ -48,3 +52,34 @@ export async function createTokenSchedule(refreshedTokens?: Array<string>) {
createTokenSchedule(await refreshToken());
}
}

async function getRootFolderMetadata(rootFolderid: number) {
try {
const res = await newAuthorizedClient.get(
`${process.env.NEW_DRIVE_URL}/drive/folders/${rootFolderid}/metadata`
);

Logger.info('[AUTH] Got root folder metadata', res.data);
return res.data;
} catch (err) {
Logger.error('[AUTH] Could not get root folder metadata', err);
if (axios.isAxiosError(err)) {
Logger.error('[Is Axios Error]', err.response?.data);
}
return null;
}
}

export async function checkUserData(): Promise<void> {
const user = getUser();
if (user?.root_folder_id && !user?.rootFolderId) {
const rootFolderMetadata = await getRootFolderMetadata(user.root_folder_id);
if (rootFolderMetadata) {
setUser({
...user,
rootFolderId: rootFolderMetadata.uuid,
});
}
refreshToken();
}
}
7 changes: 4 additions & 3 deletions src/apps/main/auth/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ export function setCredentials(
ConfigStore.set('newTokenEncrypted', isSafeStorageAvailable);
}

export function setUser(userData: User) {
ConfigStore.set('userData', userData);
}

export function updateCredentials(
bearerToken: string,
newBearerToken?: string
Expand Down Expand Up @@ -146,7 +150,6 @@ export function getUser(): User | null {
return user && Object.keys(user).length ? user : null;
}


export function obtainTokens(): Array<string> {
return tokensKeys.map(obtainToken);
}
Expand Down Expand Up @@ -220,5 +223,3 @@ export function logout() {
resetCredentials();
Logger.info('[AUTH] User logged out');
}


4 changes: 4 additions & 0 deletions src/apps/main/background-processes/sync-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import eventBus from '../event-bus';
import nodeSchedule from 'node-schedule';
import * as Sentry from '@sentry/electron/main';
import { checkSyncEngineInProcess } from '../remote-sync/handlers';
import { clearRootVirtualDrive } from '../virtual-root-folder/service';

let worker: BrowserWindow | null = null;
let workerIsRunning = false;
Expand Down Expand Up @@ -188,6 +189,8 @@ async function stopAndClearSyncEngineWatcher() {
Logger.info('[MAIN] WORKER WAS NOT RUNNING');
worker?.destroy();
worker = null;
await clearRootVirtualDrive();

return;
}

Expand Down Expand Up @@ -229,6 +232,7 @@ async function stopAndClearSyncEngineWatcher() {
worker?.destroy();
workerIsRunning = false;
worker = null;
await clearRootVirtualDrive();
}
}

Expand Down
1 change: 0 additions & 1 deletion src/apps/main/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ eventBus.on('USER_LOGGED_IN', async () => {
nativeTheme.themeSource = (configStore.get('preferedTheme') ||
'system') as Theme;

setTrayStatus('IDLE');
const widget = await getOrCreateWidged();
const tray = getTray();
if (widget && tray) {
Expand Down
7 changes: 7 additions & 0 deletions src/apps/main/preload.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ declare interface Window {

pathChanged(path: string): void;

logger: {
info: (...message: unknown[]) => void;
error: (...message: unknown[]) => void;
warn: (...message: unknown[]) => void;
debug: (...message: unknown[]) => void;
};

getGeneralIssues: () => Promise<
import('../../apps/shared/types').GeneralIssue[]
>;
Expand Down
7 changes: 7 additions & 0 deletions src/apps/main/preload.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const { contextBridge, ipcRenderer } = require('electron');
const path = require('path');
const Logger = require('electron-log');

contextBridge.exposeInMainWorld('electron', {
getConfigKey(key) {
Expand All @@ -16,6 +17,12 @@ contextBridge.exposeInMainWorld('electron', {
return () => ipcRenderer.removeListener(eventName, callback);
},

logger: {
info: (...message) => Logger.info(message),
error: (...message) => Logger.error(message),
warn: (...message) => Logger.warn(message),
},

pathChanged(pathname) {
ipcRenderer.send('path-changed', pathname);
},
Expand Down
4 changes: 2 additions & 2 deletions src/apps/main/remote-sync/RemoteSyncManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,7 @@ export class RemoteSyncManager {
);
Logger.info(
`Fetching item ${type} response: ${JSON.stringify(
response.data[0],
response.data?.length,
null,
2
)}`
Expand All @@ -700,7 +700,7 @@ export class RemoteSyncManager {
);
Logger.info(
`Fetching by folder ${type} by folder response: ${JSON.stringify(
response.data.result[0],
response.data.result?.length,
null,
2
)}`
Expand Down
10 changes: 7 additions & 3 deletions src/apps/main/remote-sync/handlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,13 @@ remoteSyncManager.onStatusChange((newStatus) => {
});

remoteSyncManager.onStatusChange((newStatus) => {
if (newStatus === 'SYNCED') {
return setTrayStatus('IDLE');
if (newStatus === 'SYNCING') {
return setTrayStatus('SYNCING');
}
setTrayStatus('SYNCING');
if (newStatus === 'SYNC_FAILED') {
return setTrayStatus('ALERT');
}
setTrayStatus('IDLE');
});

ipcMain.handle('get-remote-sync-status', () =>
Expand Down Expand Up @@ -200,6 +203,7 @@ eventBus.on('USER_LOGGED_IN', async () => {
Logger.info('Received user logged in event');
try {
remoteSyncManager.isProcessRunning = true;
setTrayStatus('SYNCING');
const userData = configStore.get('userData');
const lastFilesSyncAt = await remoteSyncManager.getFileCheckpoint();
Logger.info('Last files sync at', lastFilesSyncAt);
Expand Down
1 change: 1 addition & 0 deletions src/apps/main/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export type User = {
registerCompleted: boolean;
revocateKey: string;
root_folder_id: number;
rootFolderId: string;
sharedWorkspace: boolean;
teams: boolean;
userId: string;
Expand Down
34 changes: 20 additions & 14 deletions src/apps/main/virtual-root-folder/service.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Logger from 'electron-log';
import { app, dialog, shell } from 'electron';
import fs from 'fs/promises';
import path from 'path';
Expand Down Expand Up @@ -76,26 +77,31 @@ export function getRootVirtualDrive(): string {
return configStore.get('syncRoot');
}

export async function setupRootFolder(n = 0): Promise<void> {
setSyncRoot(VIRTUAL_DRIVE_FOLDER);
return;
const folderName = ROOT_FOLDER_NAME;
export async function clearRootVirtualDrive(): Promise<void> {
try {
const syncFolderPath = configStore.get('syncRoot');

const queue = path.join(
app.getPath('appData'),
'internxt-drive',
'queue-manager.json'
);

const rootFolderName = folderName + (n ? ` (${n})` : '');
const rootFolderPath = path.join(HOME_FOLDER_PATH, rootFolderName);
await fs.rm(queue, { recursive: true, force: true });

const notExistsOrIsEmpty =
!(await existsFolder(rootFolderPath)) ||
(await isEmptyFolder(rootFolderPath));
await fs.rm(syncFolderPath, { recursive: true, force: true });

if (notExistsOrIsEmpty) {
await fs.mkdir(rootFolderPath, { recursive: true });
setSyncRoot(rootFolderPath);
} else {
return setupRootFolder(n + 1);
Logger.info(`Directory contents cleared: ${syncFolderPath}`);
} catch (err) {
Logger.error('Error clearing root virtual drive', err);
}
}

export async function setupRootFolder(n = 0): Promise<void> {
setSyncRoot(VIRTUAL_DRIVE_FOLDER);
return;
}

export async function chooseSyncRootWithDialog(): Promise<string | null> {
const result = await dialog.showOpenDialog({ properties: ['openDirectory'] });
if (!result.canceled) {
Expand Down
6 changes: 2 additions & 4 deletions src/apps/renderer/pages/Widget/Logout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,8 @@ const ModalLogout: React.FC<ModalLogoutProps> = ({
return syncPending || wasSyncing || existFileUnsync.length > 0;
};

window.electron.updateUnsycFileInSyncEngine().then(() => {
checkSyncPending().then((value) => {
setIsSyncPending(value);
});
checkSyncPending().then((value) => {
setIsSyncPending(value);
});
}, [syncStatus]);

Expand Down
7 changes: 5 additions & 2 deletions src/apps/shared/HttpClient/HttpClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ export class AuthorizedHttpClient {
private handleUnauthorizedResponse(error: AxiosError) {
if (error?.response?.status === 401) {
Logger.warn('[AUTH] Request unauthorized');
// this.unauthorizedNotifier();
try {
this.unauthorizedNotifier();
} catch (error) {
Logger.error('[AUTH] Unauthorized notifier failed', error);
}
}

// Prevent the token from being displayed in the logs
if (error.config.headers?.Authorization) {
error.config.headers['Authorization'] = 'Bearer ****************';
Expand Down
4 changes: 3 additions & 1 deletion src/apps/shared/HttpClient/main-process-client.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { Axios } from 'axios';

import { onUserUnauthorized } from '../../main/auth/handlers';
import { getHeaders, getNewApiHeaders } from '../../main/auth/service';
import { AuthorizedClients } from './Clients';
import { AuthorizedHttpClient } from './HttpClient';
import { ipcMain } from 'electron';

const onUserUnauthorized = () => ipcMain.emit('user-is-unauthorized');

const headersProvider = () => Promise.resolve(getHeaders(false));
const newHeadersProvider = () => Promise.resolve(getNewApiHeaders());
Expand Down
Loading

0 comments on commit 706f357

Please sign in to comment.