Thank you for the detailed information!
I'm looking into the issue now. Hopefully it will be fixed soon (edit : see also this forum post )!
Is the connection with Joplin Cloud at least encrypted with TLS, even if the data is not E2EE? Or did I just send my entire database on the back of a postcard?
Joplin Cloud sync should take place over https
! (Your data should be safe!)
This is some of the relevant code
public: true,
label: () => _('Joplin Server password'),
secure: true,
},
// Although sync.10.path is essentially a constant, we still define
// it here so that both Joplin Server and Joplin Cloud can be
// handled in the same consistent way. Also having it a setting
// means it can be set to something else for development.
'sync.10.path': {
value: 'https://api.joplincloud.com',
type: SettingItemType.String,
public: false,
storage: SettingStorage.Database,
},
'sync.10.userContentPath': {
value: 'https://joplinusercontent.com',
type: SettingItemType.String,
public: false,
storage: SettingStorage.Database,
},
}
public static async checkConfig(options: FileApiOptions) {
return SyncTargetJoplinServer.checkConfig({
...options,
}, SyncTargetJoplinCloud.id());
}
protected async initFileApi() {
return initFileApi(SyncTargetJoplinCloud.id(), this.logger(), {
path: () => Setting.value('sync.10.path'),
userContentPath: () => Setting.value('sync.10.userContentPath'),
username: () => Setting.value('sync.10.username'),
password: () => Setting.value('sync.10.password'),
});
}
protected async initSynchronizer() {
return new Synchronizer(this.db(), await this.fileApi(), Setting.value('appType'));
}
}
interface FileApiOptions {
path(): string;
userContentPath(): string;
username(): string;
password(): string;
}
export async function newFileApi(id: number, options: FileApiOptions) {
const apiOptions = {
baseUrl: () => options.path(),
userContentBaseUrl: () => options.userContentPath(),
username: () => options.username(),
password: () => options.password(),
env: Setting.value('env'),
};
const api = new JoplinServerApi(apiOptions);
const driver = new FileApiDriverJoplinServer(api);
const fileApi = new FileApi('', driver);
fileApi.setSyncTargetId(id);
logger.debug(this.requestToCurl_(url, fetchOptions));
}
let response: any = null;
if (options.source === 'file' && (method === 'POST' || method === 'PUT')) {
if (fetchOptions.path) {
const fileStat = await shim.fsDriver().stat(fetchOptions.path);
if (fileStat) fetchOptions.headers['Content-Length'] = `${fileStat.size}`;
}
response = await shim.uploadBlob(url, fetchOptions);
} else if (options.target === 'string') {
if (typeof body === 'string') fetchOptions.headers['Content-Length'] = `${shim.stringByteLength(body)}`;
response = await shim.fetch(url, fetchOptions);
} else {
// file
response = await shim.fetchBlob(url, fetchOptions);
}
const responseText = await response.text();
1 Like