Merge branch 'dev' into fix_publish_note

pull/6600/head
Laurent Cozic 2022-07-12 14:48:19 +01:00 committed by GitHub
commit f1fde99d5b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 61 additions and 32 deletions

View File

@ -49,7 +49,7 @@ Coding style is enforced by a pre-commit hook that runs eslint. This hook is ins
For new React components, please use [React Hooks](https://reactjs.org/docs/hooks-intro.html). For new code in general, please use TypeScript. Even if you are modifying a file that was originally in JavaScript you should ideally convert it first to TypeScript before modifying it. Doing so is relatively easy and it helps maintain code quality.
For changes made to the Desktop client that affect the user interface, refer to `packages/app-desktop/theme.ts` for all styling information. The goal is to create a consistent user interface to allow for easy navigation of Joplin's various features and improve the overall user experience.
For changes made to the Desktop and mobile clients that affect the user interface, refer to `packages/lib/theme.ts` for all styling information. The goal is to create a consistent user interface to allow for easy navigation of Joplin's various features and improve the overall user experience.
## Automated tests

View File

@ -161,8 +161,8 @@ class NoteScreenComponent extends BaseScreenComponent {
this.onJoplinLinkClick_ = async (msg: string) => {
try {
if (msg.indexOf('joplin://') === 0) {
const resourceUrlInfo = urlUtils.parseResourceUrl(msg);
const resourceUrlInfo = urlUtils.parseResourceUrl(msg);
if (resourceUrlInfo) {
const itemId = resourceUrlInfo.itemId;
const item = await BaseItem.loadItemById(itemId);
if (!item) throw new Error(_('No item with ID %s', itemId));

View File

@ -418,7 +418,7 @@ export default class BaseItem extends BaseModel {
const share = item.share_id ? await this.shareService().shareById(item.share_id) : null;
const serialized = await ItemClass.serialize(item, shownKeys);
if (!getEncryptionEnabled() || !ItemClass.encryptionSupported() || !itemCanBeEncrypted(item)) {
if (!getEncryptionEnabled() || !ItemClass.encryptionSupported() || !itemCanBeEncrypted(item, share)) {
// Normally not possible since itemsThatNeedSync should only return decrypted items
if (item.encryption_applied) throw new JoplinError('Item is encrypted but encryption is currently disabled', 'cannotSyncEncrypted');
return serialized;

View File

@ -411,3 +411,37 @@ describe('models/Note', function() {
}));
});
describe('models/Note_replacePaths', function() {
function testResourceReplacment(body: string, pathsToTry: string[], expected: string) {
expect(Note['replaceResourceExternalToInternalLinks_'](pathsToTry, body)).toBe(expected);
}
test('Basic replacement', () => {
const body = '![image.png](file:///C:Users/Username/resources/849eae4dade045298c107fc706b6d2bc.png?t=1655192326803)';
const pathsToTry = ['file:///C:Users/Username/resources'];
const expected = '![image.png](:/849eae4dade045298c107fc706b6d2bc)';
testResourceReplacment(body, pathsToTry, expected);
});
test('Replacement with spaces', () => {
const body = '![image.png](file:///C:Users/Username%20with%20spaces/resources/849eae4dade045298c107fc706b6d2bc.png?t=1655192326803)';
const pathsToTry = ['file:///C:Users/Username with spaces/resources'];
const expected = '![image.png](:/849eae4dade045298c107fc706b6d2bc)';
testResourceReplacment(body, pathsToTry, expected);
});
test('Replacement with Non-ASCII', () => {
const body = '![image.png](file:///C:Users/UsernameWith%C3%A9%C3%A0%C3%B6/resources/849eae4dade045298c107fc706b6d2bc.png?t=1655192326803)';
const pathsToTry = ['file:///C:Users/UsernameWithéàö/resources'];
const expected = '![image.png](:/849eae4dade045298c107fc706b6d2bc)';
testResourceReplacment(body, pathsToTry, expected);
});
test('Replacement with Non-ASCII and spaces', () => {
const body = '![image.png](file:///C:Users/Username%20With%20%C3%A9%C3%A0%C3%B6/resources/849eae4dade045298c107fc706b6d2bc.png?t=1655192326803)';
const pathsToTry = ['file:///C:Users/Username With éàö/resources'];
const expected = '![image.png](:/849eae4dade045298c107fc706b6d2bc)';
testResourceReplacment(body, pathsToTry, expected);
});
});

View File

@ -182,7 +182,7 @@ export default class Note extends BaseItem {
const resourceDir = toForwardSlashes(Setting.value('resourceDir'));
let pathsToTry = [];
const pathsToTry = [];
if (options.useAbsolutePaths) {
pathsToTry.push(`file://${resourceDir}`);
pathsToTry.push(`file:///${resourceDir}`);
@ -192,6 +192,13 @@ export default class Note extends BaseItem {
pathsToTry.push(Resource.baseRelativeDirectoryPath());
}
body = Note.replaceResourceExternalToInternalLinks_(pathsToTry, body);
return body;
}
private static replaceResourceExternalToInternalLinks_(pathsToTry: string[], body: string) {
// This is a moved to a separate function for the purpose of testing only
// We support both the escaped and unescaped versions because both
// of those paths are valid:
//
@ -202,7 +209,7 @@ export default class Note extends BaseItem {
const temp = [];
for (const p of pathsToTry) {
temp.push(p);
temp.push(markdownUtils.escapeLinkUrl(p));
temp.push(encodeURI(p));
}
pathsToTry = temp;
@ -227,7 +234,6 @@ export default class Note extends BaseItem {
// Handles joplin://af0edffa4a60496bba1b0ba06b8fb39a
body = body.replace(/\(joplin:\/\/([a-zA-Z0-9]{32})\)/g, '(:/$1)');
}
// this.logger().debug('replaceResourceExternalToInternalLinks result', body);
return body;

View File

@ -207,7 +207,7 @@ export default class Resource extends BaseItem {
const share = resource.share_id ? await this.shareService().shareById(resource.share_id) : null;
if (!getEncryptionEnabled() || !itemCanBeEncrypted(resource as any)) {
if (!getEncryptionEnabled() || !itemCanBeEncrypted(resource as any, share)) {
// Normally not possible since itemsThatNeedSync should only return decrypted items
if (resource.encryption_blob_encrypted) throw new Error('Trying to access encrypted resource but encryption is currently disabled');
return { path: plainTextPath, resource: resource };

View File

@ -1,5 +1,14 @@
import { BaseItemEntity } from '../../services/database/types';
import { StateShare } from '../../services/share/reducer';
export default function(resource: BaseItemEntity): boolean {
return !resource.is_shared;
export default function(item: BaseItemEntity, share: StateShare): boolean {
// Note has been published - currently we don't encrypt
if (item.is_shared) return false;
// Item has been shared with user, but sharee is not encrypting his notes,
// so we shouldn't encrypt it either. Otherwise sharee will not be able to
// view the note anymore. https://github.com/laurent22/joplin/issues/6645
if (item.share_id && (!share || !share.master_key_id)) return false;
return true;
}

View File

@ -140,6 +140,7 @@ describe('ShareService', function() {
expect(await MasterKey.count()).toBe(1);
let { folder, note, resource } = await testShareFolder(shareService);
await Folder.updateAllShareIds(resourceService());
// The share service should automatically create a new encryption key
// specifically for that shared folder

View File

@ -1,11 +0,0 @@
// Sync object
/** @type {import('@jest/types').Config.InitialOptions} */
const config = {
preset: 'react-native',
modulePathIgnorePatterns: [
'<rootDir>/example/node_modules',
'<rootDir>/lib/',
],
};
module.exports = config;

View File

@ -15,13 +15,9 @@
"react-native-saf-x.podspec",
"!lib/typescript/example",
"!android/build",
"!ios/build",
"!**/__tests__",
"!**/__fixtures__",
"!**/__mocks__"
"!ios/build"
],
"scripts": {
"test": "jest",
"linter-precommit": "yarn --cwd ../../ eslint --resolve-plugins-relative-to . --fix packages/react-native-saf-x/**/*.{js,ts,tsx}",
"tsc": "tsc --project tsconfig.json"
},
@ -42,10 +38,8 @@
},
"devDependencies": {
"@babel/core": "^7.12.9",
"@types/jest": "^26.0.15",
"@types/react": "^16.9.55",
"@types/react-native": "^0.64.4",
"jest": "^26.6.3",
"react": "17.0.2",
"react-native": "0.66.1",
"typescript": "^4.0.5"

View File

@ -6,8 +6,6 @@
],
"exclude": [
"**/node_modules",
"tests/support/**/*",
"tests-build/**/*",
"build/**/*",
],
}

View File

@ -3517,10 +3517,8 @@ __metadata:
resolution: "@joplin/react-native-saf-x@workspace:packages/react-native-saf-x"
dependencies:
"@babel/core": ^7.12.9
"@types/jest": ^26.0.15
"@types/react": ^16.9.55
"@types/react-native": ^0.64.4
jest: ^26.6.3
react: 17.0.2
react-native: 0.66.1
typescript: ^4.0.5