1
0
mirror of https://github.com/laurent22/joplin.git synced 2026-04-21 19:45:16 +02:00

Compare commits

...

1 Commits

Author SHA1 Message Date
Laurent Cozic 1e4c3d81ba update 2026-04-15 10:30:21 +01:00
6 changed files with 44 additions and 2 deletions
+5
View File
@@ -48,6 +48,7 @@ import ShareService from '@joplin/lib/services/share/ShareService';
import checkForUpdates from './checkForUpdates';
import { AppState } from './app.reducer';
import syncDebugLog from '@joplin/lib/services/synchronizer/syncDebugLog';
import { completePendingAuthentication } from '@joplin/lib/services/joplinCloudUtils';
import eventManager, { EventName } from '@joplin/lib/eventManager';
import path = require('path');
import { afterDefaultPluginsLoaded, loadAndRunDefaultPlugins } from '@joplin/lib/services/plugins/defaultPlugins/defaultPluginsUtils';
@@ -607,6 +608,10 @@ class Application extends BaseApplication {
}
});
addTask('app/complete pending Joplin Cloud auth', async () => {
await completePendingAuthentication();
});
addTask('app/start maintenance tasks', () => {
// Always disable on Mac for now - and disable too for the few apps that may have the flag enabled.
// At present, it only seems to work on Windows.
@@ -6,7 +6,7 @@ import { clipboard } from 'electron';
import Button, { ButtonLevel } from './Button/Button';
import { uuidgen } from '@joplin/lib/uuid';
import { Dispatch } from 'redux';
import { reducer, defaultState, generateApplicationConfirmUrl, checkIfLoginWasSuccessful } from '@joplin/lib/services/joplinCloudUtils';
import { reducer, defaultState, generateApplicationConfirmUrl, checkIfLoginWasSuccessful, saveApplicationAuthId } from '@joplin/lib/services/joplinCloudUtils';
import { AppState } from '../app.reducer';
import Logger from '@joplin/utils/Logger';
import { reg } from '@joplin/lib/registry';
@@ -57,6 +57,7 @@ const JoplinCloudScreenComponent = (props: Props) => {
if (state.next === 'LINK_USED') {
dispatch({ type: 'LINK_USED' });
}
saveApplicationAuthId(applicationAuthId);
periodicallyCheckForCredentials();
};
@@ -5,7 +5,7 @@ const { connect } = require('react-redux');
const { _ } = require('@joplin/lib/locale');
const { themeStyle } = require('../global-style.js');
import { AppState } from '../../utils/types';
import { generateApplicationConfirmUrl, reducer, checkIfLoginWasSuccessful, defaultState } from '@joplin/lib/services/joplinCloudUtils';
import { generateApplicationConfirmUrl, reducer, checkIfLoginWasSuccessful, saveApplicationAuthId, defaultState } from '@joplin/lib/services/joplinCloudUtils';
import { uuidgen } from '@joplin/lib/uuid';
import { Button } from 'react-native-paper';
import createRootStyle from '../../utils/createRootStyle';
@@ -107,6 +107,7 @@ const JoplinCloudScreenComponent = (props: Props) => {
if (state.next === 'LINK_USED') {
dispatch({ type: 'LINK_USED' });
}
saveApplicationAuthId(applicationAuthId);
periodicallyCheckForCredentials();
};
@@ -13,6 +13,7 @@ import { loadKeychainServiceAndSettings } from '@joplin/lib/services/SettingUtil
import { setLocale } from '@joplin/lib/locale';
import SyncTargetJoplinServer from '@joplin/lib/SyncTargetJoplinServer';
import SyncTargetJoplinCloud from '@joplin/lib/SyncTargetJoplinCloud';
import { completePendingAuthentication } from '@joplin/lib/services/joplinCloudUtils';
import SyncTargetOneDrive from '@joplin/lib/SyncTargetOneDrive';
import initProfile from '@joplin/lib/services/profileConfig/initProfile';
const VersionInfo = require('react-native-version-info').default;
@@ -418,6 +419,9 @@ const buildStartupTasks = (
addTask('buildStartupTasks/run migrations', async () => {
await MigrationService.instance().run();
});
addTask('buildStartupTasks/complete pending Joplin Cloud auth', async () => {
await completePendingAuthentication();
});
addTask('buildStartupTasks/set up background tasks', async () => {
initializeUserFetcher();
PoorManIntervals.setInterval(() => { void userFetcher(); }, 1000 * 60 * 60);
@@ -445,6 +445,8 @@ const builtInMetadata = (Setting: typeof SettingType) => {
secure: true,
},
'sync.10.pendingAuthId': { value: '', type: SettingItemType.String, public: false },
'sync.10.inboxEmail': { value: '', type: SettingItemType.String, public: false },
'sync.10.inboxId': { value: '', type: SettingItemType.String, public: false },
+29
View File
@@ -6,6 +6,9 @@ import { _ } from '../locale';
import eventManager, { EventName } from '../eventManager';
import { reg } from '../registry';
import SyncTargetRegistry from '../SyncTargetRegistry';
import Logger from '@joplin/utils/Logger';
const logger = Logger.create('joplinCloudUtils');
type ActionType = 'LINK_USED' | 'COMPLETED' | 'ERROR';
type Action = {
@@ -90,6 +93,9 @@ export const generateApplicationConfirmUrl = async (confirmUrl: string) => {
return `${confirmUrl}?${searchParams.toString()}`;
};
export const saveApplicationAuthId = (applicationAuthId: string) => {
Setting.setValue('sync.10.pendingAuthId', applicationAuthId);
};
// We have isWaitingResponse inside the function to avoid any state from lingering
// after an error occurs. E.g.: if the function would throw an error while isWaitingResponse
@@ -116,6 +122,7 @@ export const checkIfLoginWasSuccessful = async (applicationsUrl: string) => {
Setting.setValue('sync.10.username', jsonBody.id);
Setting.setValue('sync.10.password', jsonBody.password);
Setting.setValue('sync.target', SyncTargetRegistry.nameToId('joplinCloud'));
Setting.setValue('sync.10.pendingAuthId', '');
const fileApi = await reg.syncTarget().fileApi();
await fileApi.driver().api().loadSession();
@@ -126,3 +133,25 @@ export const checkIfLoginWasSuccessful = async (applicationsUrl: string) => {
return performLoginRequest();
};
// If the app was killed during the OAuth flow (common on Android), the
// pending auth ID is still saved. On startup we check whether the server
// has already confirmed the authorisation and, if so, save the credentials.
export const completePendingAuthentication = async () => {
const pendingAuthId = Setting.value('sync.10.pendingAuthId');
if (!pendingAuthId) return;
const apiBaseUrl = Setting.value('sync.10.path');
const applicationsUrl = `${apiBaseUrl}/api/application_auth/${pendingAuthId}`;
try {
const result = await checkIfLoginWasSuccessful(applicationsUrl);
if (result && result.success) {
logger.info('Completed pending Joplin Cloud authentication');
}
} catch (error) {
logger.error('Could not complete pending authentication:', error);
} finally {
Setting.setValue('sync.10.pendingAuthId', '');
}
};