1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-01-17 18:44:45 +02:00

All: Fixed user content URLs when sharing note via Joplin Server

This commit is contained in:
Laurent Cozic 2021-06-15 12:25:55 +01:00
parent 58f8d7e1b4
commit 2cf70675dc
9 changed files with 43 additions and 19 deletions

View File

@ -1169,6 +1169,9 @@ packages/lib/services/interop/InteropService_Importer_Raw.js.map
packages/lib/services/interop/types.d.ts packages/lib/services/interop/types.d.ts
packages/lib/services/interop/types.js packages/lib/services/interop/types.js
packages/lib/services/interop/types.js.map packages/lib/services/interop/types.js.map
packages/lib/services/joplinServer/personalizedUserContentBaseUrl.d.ts
packages/lib/services/joplinServer/personalizedUserContentBaseUrl.js
packages/lib/services/joplinServer/personalizedUserContentBaseUrl.js.map
packages/lib/services/keychain/KeychainService.d.ts packages/lib/services/keychain/KeychainService.d.ts
packages/lib/services/keychain/KeychainService.js packages/lib/services/keychain/KeychainService.js
packages/lib/services/keychain/KeychainService.js.map packages/lib/services/keychain/KeychainService.js.map

3
.gitignore vendored
View File

@ -1155,6 +1155,9 @@ packages/lib/services/interop/InteropService_Importer_Raw.js.map
packages/lib/services/interop/types.d.ts packages/lib/services/interop/types.d.ts
packages/lib/services/interop/types.js packages/lib/services/interop/types.js
packages/lib/services/interop/types.js.map packages/lib/services/interop/types.js.map
packages/lib/services/joplinServer/personalizedUserContentBaseUrl.d.ts
packages/lib/services/joplinServer/personalizedUserContentBaseUrl.js
packages/lib/services/joplinServer/personalizedUserContentBaseUrl.js.map
packages/lib/services/keychain/KeychainService.d.ts packages/lib/services/keychain/KeychainService.d.ts
packages/lib/services/keychain/KeychainService.js packages/lib/services/keychain/KeychainService.js
packages/lib/services/keychain/KeychainService.js.map packages/lib/services/keychain/KeychainService.js.map

View File

@ -26,7 +26,7 @@ if [ "$RESET_ALL" == "1" ]; then
echo "config keychain.supported 0" >> "$CMD_FILE" echo "config keychain.supported 0" >> "$CMD_FILE"
echo "config sync.target 10" >> "$CMD_FILE" echo "config sync.target 10" >> "$CMD_FILE"
echo "config sync.10.path http://api.joplincloud.local:22300" >> "$CMD_FILE" # echo "config sync.10.path http://api.joplincloud.local:22300" >> "$CMD_FILE"
echo "config sync.10.username $USER_EMAIL" >> "$CMD_FILE" echo "config sync.10.username $USER_EMAIL" >> "$CMD_FILE"
echo "config sync.10.password 123456" >> "$CMD_FILE" echo "config sync.10.password 123456" >> "$CMD_FILE"
@ -45,4 +45,4 @@ if [ "$RESET_ALL" == "1" ]; then
fi fi
cd "$ROOT_DIR/packages/app-desktop" cd "$ROOT_DIR/packages/app-desktop"
npm start -- --profile "$PROFILE_DIR" npm start -- --env dev --profile "$PROFILE_DIR"

View File

@ -766,10 +766,10 @@ export default class BaseApplication {
} }
if (Setting.value('env') === Env.Dev) { if (Setting.value('env') === Env.Dev) {
Setting.setValue('sync.10.path', 'https://api.joplincloud.com'); // Setting.setValue('sync.10.path', 'https://api.joplincloud.com');
Setting.setValue('sync.10.userContentPath', 'https://joplinusercontent.com'); // Setting.setValue('sync.10.userContentPath', 'https://joplinusercontent.com');
// Setting.setValue('sync.10.path', 'http://api.joplincloud.local:22300'); Setting.setValue('sync.10.path', 'http://api.joplincloud.local:22300');
// Setting.setValue('sync.10.userContentPath', 'http://joplinusercontent.local:22300'); Setting.setValue('sync.10.userContentPath', 'http://joplinusercontent.local:22300');
} }
// For now always disable fuzzy search due to performance issues: // For now always disable fuzzy search due to performance issues:

View File

@ -4,6 +4,7 @@ const { rtrimSlashes } = require('./path-utils.js');
import JoplinError from './JoplinError'; import JoplinError from './JoplinError';
import { Env } from './models/Setting'; import { Env } from './models/Setting';
import Logger from './Logger'; import Logger from './Logger';
import personalizedUserContentBaseUrl from './services/joplinServer/personalizedUserContentBaseUrl';
const { stringify } = require('query-string'); const { stringify } = require('query-string');
const logger = Logger.create('JoplinServerApi'); const logger = Logger.create('JoplinServerApi');
@ -56,14 +57,8 @@ export default class JoplinServerApi {
return rtrimSlashes(this.options_.baseUrl()); return rtrimSlashes(this.options_.baseUrl());
} }
public userContentBaseUrl(userId: string) { public personalizedUserContentBaseUrl(userId: string) {
if (this.options_.userContentBaseUrl()) { return personalizedUserContentBaseUrl(userId, this.baseUrl(), this.options_.userContentBaseUrl());
if (!userId) throw new Error('User ID must be specified');
const url = new URL(this.options_.userContentBaseUrl());
return `${url.protocol}//${userId.substr(0, 10).toLowerCase()}.${url.host}`;
} else {
return this.baseUrl();
}
} }
private async session() { private async session() {

View File

@ -0,0 +1,18 @@
// For this:
//
// userId: d67VzcrHs6zGzROagnzwhOZJI0vKbezc
// baseUrl: http://example.com
// userContentBaseUrl: http://usercontent.com
//
// => Returns http://d67Vzcrhs6.usercontent.com
//
// If the userContentBaseUrl is an empty string, the baseUrl is returned instead.
export default function(userId: string, baseUrl: string, userContentBaseUrl: string) {
if (userContentBaseUrl) {
if (!userId) throw new Error('User ID must be specified');
const url = new URL(userContentBaseUrl);
return `${url.protocol}//${userId.substr(0, 10).toLowerCase()}.${url.host}`;
} else {
return baseUrl;
}
}

View File

@ -5,6 +5,7 @@ import { ErrorUnprocessableEntity, ErrorBadRequest } from '../utils/errors';
import { Models } from './factory'; import { Models } from './factory';
import * as EventEmitter from 'events'; import * as EventEmitter from 'events';
import { Config } from '../utils/types'; import { Config } from '../utils/types';
import personalizedUserContentBaseUrl from '@joplin/lib/services/joplinServer/personalizedUserContentBaseUrl';
export interface SaveOptions { export interface SaveOptions {
isNew?: boolean; isNew?: boolean;
@ -64,10 +65,14 @@ export default abstract class BaseModel<T> {
return this.config_.baseUrl; return this.config_.baseUrl;
} }
protected get userContentUrl(): string { protected get userContentBaseUrl(): string {
return this.config_.userContentBaseUrl; return this.config_.userContentBaseUrl;
} }
protected personalizedUserContentBaseUrl(userId: Uuid): string {
return personalizedUserContentBaseUrl(userId, this.baseUrl, this.userContentBaseUrl);
}
protected get appName(): string { protected get appName(): string {
return this.config_.appName; return this.config_.appName;
} }

View File

@ -35,7 +35,7 @@ export default class ShareModel extends BaseModel<Share> {
} }
public checkShareUrl(share: Share, shareUrl: string) { public checkShareUrl(share: Share, shareUrl: string) {
if (this.baseUrl === this.userContentUrl) return; // OK if (this.baseUrl === this.userContentBaseUrl) return; // OK
const userId = userIdFromUserContentUrl(shareUrl); const userId = userIdFromUserContentUrl(shareUrl);
const shareUserId = share.owner_id.toLowerCase(); const shareUserId = share.owner_id.toLowerCase();
@ -93,8 +93,8 @@ export default class ShareModel extends BaseModel<Share> {
return !!r; return !!r;
} }
public shareUrl(id: Uuid, query: any = null): string { public shareUrl(shareOwnerId: Uuid, id: Uuid, query: any = null): string {
return setQueryParameters(`${this.userContentUrl}/shares/${id}`, query); return setQueryParameters(`${this.personalizedUserContentBaseUrl(shareOwnerId)}/shares/${id}`, query);
} }
public async byItemId(itemId: Uuid): Promise<Share | null> { public async byItemId(itemId: Uuid): Promise<Share | null> {

View File

@ -177,7 +177,7 @@ async function renderNote(share: Share, note: NoteEntity, resourceInfos: Resourc
if (item.type_ === ModelType.Note) { if (item.type_ === ModelType.Note) {
return '#'; return '#';
} else if (item.type_ === ModelType.Resource) { } else if (item.type_ === ModelType.Resource) {
return `${models_.share().shareUrl(share.id)}?resource_id=${item.id}&t=${item.updated_time}`; return `${models_.share().shareUrl(share.owner_id, share.id)}?resource_id=${item.id}&t=${item.updated_time}`;
} else { } else {
throw new Error(`Unsupported item type: ${item.type_}`); throw new Error(`Unsupported item type: ${item.type_}`);
} }