You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-12-08 23:07:32 +02:00
Compare commits
18 Commits
v3.5.3
...
plugin-gen
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d1aec4a9f7 | ||
|
|
cab1525589 | ||
|
|
a52f3fea9e | ||
|
|
dfbd5eb8ed | ||
|
|
3131f36033 | ||
|
|
dc5b2cfa21 | ||
|
|
cad0f35fcc | ||
|
|
38ea92ff57 | ||
|
|
830deada22 | ||
|
|
38cd4033ea | ||
|
|
02900752d9 | ||
|
|
091e9813b5 | ||
|
|
e61e5ac32a | ||
|
|
414970c9a1 | ||
|
|
d4ed49ff23 | ||
|
|
8751d5d152 | ||
|
|
2e846fe15d | ||
|
|
e54b7696d9 |
@@ -844,6 +844,7 @@ packages/app-mobile/components/screens/NoteTagsDialog.js
|
||||
packages/app-mobile/components/screens/Notes/NewNoteButton.test.js
|
||||
packages/app-mobile/components/screens/Notes/NewNoteButton.js
|
||||
packages/app-mobile/components/screens/Notes/Notes.js
|
||||
packages/app-mobile/components/screens/SearchScreen/SearchResults.test.js
|
||||
packages/app-mobile/components/screens/SearchScreen/SearchResults.js
|
||||
packages/app-mobile/components/screens/SearchScreen/index.js
|
||||
packages/app-mobile/components/screens/ShareManager/AcceptedShareItem.js
|
||||
@@ -1742,6 +1743,7 @@ packages/plugin-repo-cli/lib/gitCompareUrl.test.js
|
||||
packages/plugin-repo-cli/lib/gitCompareUrl.js
|
||||
packages/plugin-repo-cli/lib/overrideUtils.test.js
|
||||
packages/plugin-repo-cli/lib/overrideUtils.js
|
||||
packages/plugin-repo-cli/lib/searchPlugins.js
|
||||
packages/plugin-repo-cli/lib/types.js
|
||||
packages/plugin-repo-cli/lib/updateReadme.test.js
|
||||
packages/plugin-repo-cli/lib/updateReadme.js
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -817,6 +817,7 @@ packages/app-mobile/components/screens/NoteTagsDialog.js
|
||||
packages/app-mobile/components/screens/Notes/NewNoteButton.test.js
|
||||
packages/app-mobile/components/screens/Notes/NewNoteButton.js
|
||||
packages/app-mobile/components/screens/Notes/Notes.js
|
||||
packages/app-mobile/components/screens/SearchScreen/SearchResults.test.js
|
||||
packages/app-mobile/components/screens/SearchScreen/SearchResults.js
|
||||
packages/app-mobile/components/screens/SearchScreen/index.js
|
||||
packages/app-mobile/components/screens/ShareManager/AcceptedShareItem.js
|
||||
@@ -1715,6 +1716,7 @@ packages/plugin-repo-cli/lib/gitCompareUrl.test.js
|
||||
packages/plugin-repo-cli/lib/gitCompareUrl.js
|
||||
packages/plugin-repo-cli/lib/overrideUtils.test.js
|
||||
packages/plugin-repo-cli/lib/overrideUtils.js
|
||||
packages/plugin-repo-cli/lib/searchPlugins.js
|
||||
packages/plugin-repo-cli/lib/types.js
|
||||
packages/plugin-repo-cli/lib/updateReadme.test.js
|
||||
packages/plugin-repo-cli/lib/updateReadme.js
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
"@joplin/tools": "~3.5",
|
||||
"@types/fs-extra": "11.0.4",
|
||||
"@types/jest": "29.5.14",
|
||||
"@types/node": "18.19.118",
|
||||
"@types/node": "18.19.119",
|
||||
"@types/proper-lockfile": "^4.1.2",
|
||||
"gulp": "4.0.2",
|
||||
"jest": "29.7.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@joplin/app-desktop",
|
||||
"version": "3.5.3",
|
||||
"version": "3.5.4",
|
||||
"description": "Joplin for Desktop",
|
||||
"main": "main.bundle.js",
|
||||
"private": true,
|
||||
@@ -148,7 +148,7 @@
|
||||
"@testing-library/react-hooks": "8.0.1",
|
||||
"@types/jest": "29.5.14",
|
||||
"@types/mustache": "4.2.6",
|
||||
"@types/node": "18.19.118",
|
||||
"@types/node": "18.19.119",
|
||||
"@types/react": "18.3.23",
|
||||
"@types/react-dom": "18.3.7",
|
||||
"@types/react-redux": "7.1.33",
|
||||
|
||||
@@ -4,13 +4,25 @@ const { execSync } = require('child_process');
|
||||
const { chdir, cwd } = require('process');
|
||||
const { mkdirpSync, moveSync, pathExists } = require('fs-extra');
|
||||
const { readdirSync, writeFileSync } = require('fs');
|
||||
const { dirname } = require('path');
|
||||
|
||||
const signToolName = 'CodeSignTool.bat';
|
||||
|
||||
const getTempDir = () => {
|
||||
if (process.env.RUNNER_TEMP) return process.env.RUNNER_TEMP;
|
||||
if (process.env.GITHUB_WORKSPACE) return process.env.GITHUB_WORKSPACE;
|
||||
|
||||
const output = `${dirname(dirname(__dirname))}/temp`;
|
||||
mkdirpSync(output);
|
||||
return output;
|
||||
};
|
||||
|
||||
const tempDir = getTempDir();
|
||||
|
||||
const downloadSignTool = async () => {
|
||||
const signToolUrl = 'https://www.ssl.com/download/codesigntool-for-windows/';
|
||||
const downloadDir = `${__dirname}/signToolDownloadTemp`;
|
||||
const extractDir = `${__dirname}/signToolExtractTemp`;
|
||||
const downloadDir = `${tempDir}/signToolDownloadTemp`;
|
||||
const extractDir = `${tempDir}/signToolExtractTemp`;
|
||||
|
||||
if (await pathExists(`${extractDir}/${signToolName}`)) {
|
||||
console.info('sign.js: Sign tool has already been downloaded - skipping');
|
||||
@@ -55,6 +67,8 @@ exports.default = async (configuration) => {
|
||||
|
||||
console.info('sign.js: File to sign:', inputFilePath);
|
||||
|
||||
console.info('sign.js: Using temp dir:', tempDir);
|
||||
|
||||
if (SIGN_APPLICATION !== '1') {
|
||||
console.info('sign.js: SIGN_APPLICATION != 1 - not signing application');
|
||||
return;
|
||||
@@ -63,9 +77,8 @@ exports.default = async (configuration) => {
|
||||
console.info('sign.js: SIGN_APPLICATION = 1 - signing application');
|
||||
|
||||
const signToolDir = await downloadSignTool();
|
||||
const tempDir = `${__dirname}/temp`;
|
||||
|
||||
mkdirpSync(tempDir);
|
||||
const signToolOutDir = `${tempDir}/signedToolOutDir`;
|
||||
mkdirpSync(signToolOutDir);
|
||||
|
||||
const previousDir = cwd();
|
||||
chdir(signToolDir);
|
||||
@@ -74,7 +87,7 @@ exports.default = async (configuration) => {
|
||||
const cmd = [
|
||||
`${signToolName} sign`,
|
||||
`-input_file_path="${inputFilePath}"`,
|
||||
`-output_dir_path="${tempDir}"`,
|
||||
`-output_dir_path="${signToolOutDir}"`,
|
||||
`-credential_id="${SSL_ESIGNER_CREDENTIAL_ID}"`,
|
||||
`-username="${SSL_ESIGNER_USER_NAME}"`,
|
||||
`-password="${SSL_ESIGNER_USER_PASSWORD}"`,
|
||||
@@ -83,10 +96,10 @@ exports.default = async (configuration) => {
|
||||
|
||||
execSync(cmd.join(' '));
|
||||
|
||||
const createdFiles = readdirSync(tempDir);
|
||||
const createdFiles = readdirSync(signToolOutDir);
|
||||
console.info('sign.js: Created files:', createdFiles);
|
||||
|
||||
moveSync(`${tempDir}/${createdFiles[0]}`, inputFilePath, { overwrite: true });
|
||||
moveSync(`${signToolOutDir}/${createdFiles[0]}`, inputFilePath, { overwrite: true });
|
||||
} catch (error) {
|
||||
console.error('sign.js: Could not sign file:', error);
|
||||
process.exit(1);
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
import * as React from 'react';
|
||||
import { AppState } from '../../../utils/types';
|
||||
import { Store } from 'redux';
|
||||
import { setupDatabaseAndSynchronizer, switchClient } from '@joplin/lib/testing/test-utils';
|
||||
import createMockReduxStore from '../../../utils/testing/createMockReduxStore';
|
||||
import setupGlobalStore from '../../../utils/testing/setupGlobalStore';
|
||||
import Note from '@joplin/lib/models/Note';
|
||||
import { render, screen } from '../../../utils/testing/testingLibrary';
|
||||
import SearchResults from './SearchResults';
|
||||
import SearchEngine from '@joplin/lib/services/search/SearchEngine';
|
||||
import Folder from '@joplin/lib/models/Folder';
|
||||
import TestProviderStack from '../../testing/TestProviderStack';
|
||||
|
||||
const createNotes = async (count: number) => {
|
||||
const folder = await Folder.save({ title: 'Test Note' });
|
||||
for (let i = 0; i < count; i++) {
|
||||
await Note.save({ title: `abcd ${i}`, body: 'body', parent_id: folder.id });
|
||||
}
|
||||
await SearchEngine.instance().syncTables();
|
||||
};
|
||||
|
||||
let store: Store<AppState>;
|
||||
|
||||
interface WrapperProps {
|
||||
query: string;
|
||||
paused: boolean;
|
||||
}
|
||||
const WrappedSearchResults: React.FC<WrapperProps> = props => (
|
||||
<TestProviderStack store={store}>
|
||||
<SearchResults paused={props.paused} query={props.query} onHighlightedWordsChange={() => { }} ftsEnabled={1} />
|
||||
</TestProviderStack>
|
||||
);
|
||||
|
||||
describe('SearchResult', () => {
|
||||
beforeEach(async () => {
|
||||
await setupDatabaseAndSynchronizer(1);
|
||||
await switchClient(1);
|
||||
store = createMockReduxStore();
|
||||
setupGlobalStore(store);
|
||||
});
|
||||
|
||||
test('should show results when unpaused', async () => {
|
||||
const noteCount = 8;
|
||||
await createNotes(noteCount);
|
||||
|
||||
render(<WrappedSearchResults query='abcd' paused={false}/>);
|
||||
const items = await screen.findAllByText(/abcd \d\d?\d?/);
|
||||
expect(items.length).toBe(noteCount);
|
||||
});
|
||||
});
|
||||
@@ -13,6 +13,7 @@ import shim from '@joplin/lib/shim';
|
||||
|
||||
interface Props {
|
||||
query: string;
|
||||
paused: boolean;
|
||||
onHighlightedWordsChange: (highlightedWords: (ComplexTerm | string)[])=> void;
|
||||
|
||||
ftsEnabled: number;
|
||||
@@ -28,7 +29,7 @@ const useResults = (props: Props) => {
|
||||
let notes: NoteEntity[] = [];
|
||||
setIsProcessing(true);
|
||||
try {
|
||||
if (query) {
|
||||
if (query && !props.paused) {
|
||||
if (ftsEnabled) {
|
||||
const r = await SearchEngineUtils.notesForQuery(query, true, { appendWildCards: true });
|
||||
notes = r.notes;
|
||||
@@ -57,7 +58,7 @@ const useResults = (props: Props) => {
|
||||
} finally {
|
||||
setIsProcessing(false);
|
||||
}
|
||||
}, [query, ftsEnabled], { interval: 200 });
|
||||
}, [query, props.paused, ftsEnabled], { interval: 200 });
|
||||
|
||||
return {
|
||||
notes,
|
||||
|
||||
@@ -53,11 +53,36 @@ const useStyles = (theme: ThemeStyle, visible: boolean) => {
|
||||
}, [theme, visible]);
|
||||
};
|
||||
|
||||
// Workaround for https://github.com/laurent22/joplin/issues/12823:
|
||||
// Disable search-as-you-type for short 0-2 character searches that
|
||||
// are likely to match the start of a large number of words.
|
||||
const useSearchPaused = (query: string) => {
|
||||
const [pauseDisabled, setPauseDisabled] = useState(false);
|
||||
// Only disable search-as-you-type for a subset of all characters.
|
||||
// This is, for example, to ensure that search-as-you-type remains
|
||||
// enabled for CJK characters (e.g. U+6570 has length 1).
|
||||
const paused = query.match(/^[a-z0-9]{0,2}$/i);
|
||||
|
||||
const onOverridePause = useCallback(() => {
|
||||
setPauseDisabled(true);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setPauseDisabled(false);
|
||||
}, [query]);
|
||||
|
||||
return {
|
||||
paused: paused && !pauseDisabled,
|
||||
onOverridePause,
|
||||
};
|
||||
};
|
||||
|
||||
const SearchScreenComponent: React.FC<Props> = props => {
|
||||
const theme = themeStyle(props.themeId);
|
||||
const styles = useStyles(theme, props.visible);
|
||||
|
||||
const [query, setQuery] = useState(props.query);
|
||||
const { paused, onOverridePause } = useSearchPaused(query);
|
||||
|
||||
const globalQueryRef = useRef(props.query);
|
||||
globalQueryRef.current = props.query;
|
||||
@@ -99,6 +124,7 @@ const SearchScreenComponent: React.FC<Props> = props => {
|
||||
autoFocus={props.visible}
|
||||
underlineColorAndroid="#ffffff00"
|
||||
onChangeText={setQuery}
|
||||
onSubmitEditing={onOverridePause}
|
||||
value={query}
|
||||
selectionColor={theme.textSelectionColor}
|
||||
keyboardAppearance={theme.keyboardAppearance}
|
||||
@@ -114,6 +140,7 @@ const SearchScreenComponent: React.FC<Props> = props => {
|
||||
|
||||
<SearchResults
|
||||
query={query}
|
||||
paused={paused}
|
||||
ftsEnabled={props.ftsEnabled}
|
||||
onHighlightedWordsChange={onHighlightedWordsChange}
|
||||
/>
|
||||
|
||||
@@ -41,9 +41,9 @@
|
||||
"crypto-browserify": "3.12.1",
|
||||
"deprecated-react-native-prop-types": "5.0.0",
|
||||
"events": "3.3.0",
|
||||
"expo": "53.0.19",
|
||||
"expo": "53.0.20",
|
||||
"expo-av": "15.1.7",
|
||||
"expo-camera": "16.1.10",
|
||||
"expo-camera": "16.1.11",
|
||||
"expo-local-authentication": "16.0.5",
|
||||
"lodash": "4.17.21",
|
||||
"md5": "2.3.0",
|
||||
@@ -99,17 +99,17 @@
|
||||
"@react-native-community/cli": "16.0.3",
|
||||
"@react-native-community/cli-platform-android": "16.0.3",
|
||||
"@react-native-community/cli-platform-ios": "16.0.3",
|
||||
"@react-native/babel-preset": "0.79.5",
|
||||
"@react-native/babel-preset": "0.80.1",
|
||||
"@react-native/metro-config": "0.79.5",
|
||||
"@react-native/typescript-config": "0.79.5",
|
||||
"@sqlite.org/sqlite-wasm": "3.46.0-build2",
|
||||
"@testing-library/react-native": "13.2.0",
|
||||
"@types/fs-extra": "11.0.4",
|
||||
"@types/jest": "29.5.14",
|
||||
"@types/node": "18.19.118",
|
||||
"@types/node": "18.19.119",
|
||||
"@types/react": "19.0.14",
|
||||
"@types/react-redux": "7.1.33",
|
||||
"@types/serviceworker": "0.0.141",
|
||||
"@types/serviceworker": "0.0.142",
|
||||
"@types/tar-stream": "3.1.4",
|
||||
"babel-jest": "29.7.0",
|
||||
"babel-loader": "9.1.3",
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
"@joplin/utils": "~3.5",
|
||||
"@testing-library/react-hooks": "8.0.1",
|
||||
"@types/jest": "29.5.14",
|
||||
"@types/node": "18.19.118",
|
||||
"@types/node": "18.19.119",
|
||||
"@types/react": "18.3.23",
|
||||
"@types/react-redux": "7.1.33",
|
||||
"@types/styled-components": "5.1.32",
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "29.5.14",
|
||||
"@types/node": "18.19.118",
|
||||
"@types/node": "18.19.119",
|
||||
"@typescript-eslint/eslint-plugin": "6.21.0",
|
||||
"@typescript-eslint/parser": "6.21.0",
|
||||
"coveralls": "3.1.1",
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "29.5.14",
|
||||
"@types/node": "18.19.118",
|
||||
"@types/node": "18.19.119",
|
||||
"jest": "29.7.0",
|
||||
"typescript": "5.8.3"
|
||||
},
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { ClipboardContent } from './types';
|
||||
export default class JoplinClipboard {
|
||||
private electronClipboard_;
|
||||
private electronNativeImage_;
|
||||
@@ -26,4 +27,19 @@ export default class JoplinClipboard {
|
||||
* For example [ 'text/plain', 'text/html' ]
|
||||
*/
|
||||
availableFormats(): Promise<string[]>;
|
||||
/**
|
||||
* Writes multiple formats to the clipboard simultaneously.
|
||||
* This allows setting both text/plain and text/html at the same time.
|
||||
*
|
||||
* <span class="platform-desktop">desktop</span>
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* await joplin.clipboard.write({
|
||||
* text: 'Plain text version',
|
||||
* html: '<strong>HTML version</strong>'
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
write(content: ClipboardContent): Promise<void>;
|
||||
}
|
||||
|
||||
@@ -588,6 +588,30 @@ export interface SettingSection {
|
||||
*/
|
||||
export type Path = string[];
|
||||
|
||||
// =================================================================
|
||||
// Clipboard API types
|
||||
// =================================================================
|
||||
|
||||
/**
|
||||
* Represents content that can be written to the clipboard in multiple formats.
|
||||
*/
|
||||
export interface ClipboardContent {
|
||||
/**
|
||||
* Plain text representation of the content
|
||||
*/
|
||||
text?: string;
|
||||
|
||||
/**
|
||||
* HTML representation of the content
|
||||
*/
|
||||
html?: string;
|
||||
|
||||
/**
|
||||
* Image in [data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs) format
|
||||
*/
|
||||
image?: string;
|
||||
}
|
||||
|
||||
// =================================================================
|
||||
// Content Script types
|
||||
// =================================================================
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "generator-joplin",
|
||||
"version": "3.5.0",
|
||||
"version": "3.5.1",
|
||||
"description": "Scaffolds out a new Joplin plugin",
|
||||
"homepage": "https://github.com/laurent22/joplin/tree/dev/packages/generator-joplin",
|
||||
"author": {
|
||||
@@ -38,4 +38,4 @@
|
||||
"repository": "https://github.com/laurent22/generator-joplin",
|
||||
"license": "AGPL-3.0-or-later",
|
||||
"private": true
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@
|
||||
"@types/jsdom": "21.1.7",
|
||||
"@types/markdown-it": "13.0.9",
|
||||
"@types/mustache": "4.2.6",
|
||||
"@types/node": "18.19.118",
|
||||
"@types/node": "18.19.119",
|
||||
"@types/node-rsa": "1.1.4",
|
||||
"@types/react": "18.3.23",
|
||||
"@types/uuid": "10.0.0",
|
||||
@@ -67,7 +67,7 @@
|
||||
"fast-xml-parser": "3.21.1",
|
||||
"file-type": "16.5.4",
|
||||
"follow-redirects": "1.15.6",
|
||||
"form-data": "4.0.3",
|
||||
"form-data": "4.0.4",
|
||||
"fs-extra": "11.2.0",
|
||||
"hpagent": "1.2.0",
|
||||
"html-entities": "1.4.0",
|
||||
|
||||
@@ -71,6 +71,7 @@ import { Store } from 'redux';
|
||||
import { dirname } from '@joplin/utils/path';
|
||||
import SyncTargetJoplinServerSAML from '../SyncTargetJoplinServerSAML';
|
||||
import { MarkupLanguage } from '@joplin/renderer';
|
||||
import SearchEngine from '../services/search/SearchEngine';
|
||||
|
||||
// Each suite has its own separate data and temp directory so that multiple
|
||||
// suites can be run at the same time. suiteName is what is used to
|
||||
@@ -287,6 +288,7 @@ async function switchClient(id: number, options: any = null) {
|
||||
currentClient_ = id;
|
||||
BaseModel.setDb(databases_[id]);
|
||||
KvStore.instance().setDb(databases_[id]);
|
||||
SearchEngine.instance().setDb(databases_[id]);
|
||||
|
||||
BaseItem.encryptionService_ = encryptionServices_[id];
|
||||
Resource.encryptionService_ = encryptionServices_[id];
|
||||
|
||||
@@ -16,9 +16,9 @@ import { isJoplinPluginPackage, readJsonFile } from './lib/utils';
|
||||
import { applyManifestOverrides, getObsoleteManifests, getSupersededPackages, readManifestOverrides } from './lib/overrideUtils';
|
||||
import { execCommand } from '@joplin/utils';
|
||||
import validateUntrustedManifest from './lib/validateUntrustedManifest';
|
||||
import searchPlugins, { PackageInfo } from './lib/searchPlugins';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
|
||||
function pluginInfoFromSearchResults(results: any[]): NpmPackage[] {
|
||||
function pluginInfoFromSearchResults(results: PackageInfo[]): NpmPackage[] {
|
||||
const output: NpmPackage[] = [];
|
||||
|
||||
for (const r of results) {
|
||||
@@ -245,8 +245,7 @@ async function commandBuild(args: CommandBuildArgs) {
|
||||
|
||||
chdir(previousDir);
|
||||
|
||||
const searchResults = (await execCommand('npm search keywords:joplin-plugin --searchlimit 5000 --json', { showStdout: false, showStderr: false })).trim();
|
||||
const npmPackages = pluginInfoFromSearchResults(JSON.parse(searchResults));
|
||||
const npmPackages = pluginInfoFromSearchResults(await searchPlugins());
|
||||
|
||||
for (const npmPackage of npmPackages) {
|
||||
await processNpmPackage(npmPackage, repoDir, dryRun);
|
||||
|
||||
79
packages/plugin-repo-cli/lib/searchPlugins.ts
Normal file
79
packages/plugin-repo-cli/lib/searchPlugins.ts
Normal file
@@ -0,0 +1,79 @@
|
||||
import { URLSearchParams } from 'node:url';
|
||||
|
||||
export interface PackageInfo {
|
||||
name: string;
|
||||
version: string;
|
||||
date: string;
|
||||
keywords: string[];
|
||||
}
|
||||
|
||||
interface SearchResult {
|
||||
package: PackageInfo;
|
||||
}
|
||||
|
||||
interface SearchResponse {
|
||||
objects: SearchResult[];
|
||||
total: number;
|
||||
}
|
||||
|
||||
function validateResponse(response: unknown): asserts response is SearchResponse {
|
||||
if (typeof response !== 'object') throw new Error('Invalid response (must be an object)');
|
||||
if (!('total' in response) || typeof response.total !== 'number') {
|
||||
throw new Error('Invalid response.total');
|
||||
}
|
||||
if (!('objects' in response) || !Array.isArray(response.objects)) {
|
||||
throw new Error('response.objects must be an array');
|
||||
}
|
||||
for (const object of response.objects) {
|
||||
if (!('package' in object)) throw new Error('Missing "package" field');
|
||||
const packageField = object.package;
|
||||
if (typeof packageField.name !== 'string') throw new Error('package.name: Invalid type');
|
||||
if (typeof packageField.version !== 'string') throw new Error('package.version: Invalid type');
|
||||
if (typeof packageField.date !== 'string') throw new Error('package.date: Invalid type');
|
||||
if (!Array.isArray(packageField.keywords)) throw new Error('package.keywords: Invalid type');
|
||||
}
|
||||
}
|
||||
|
||||
const searchPlugins = async () => {
|
||||
const pageSize = 100;
|
||||
const makeRequest = async (start: number): Promise<SearchResponse> => {
|
||||
const urlParams = new URLSearchParams({
|
||||
text: 'keywords:joplin-plugin',
|
||||
size: String(pageSize),
|
||||
from: String(start),
|
||||
});
|
||||
// API documentation: https://github.com/npm/registry/blob/main/docs/REGISTRY-API.md#get-v1search
|
||||
const query = `https://registry.npmjs.org/-/v1/search?${urlParams.toString()}`;
|
||||
const result = await fetch(query);
|
||||
const json: unknown = await result.json();
|
||||
validateResponse(json);
|
||||
return json;
|
||||
};
|
||||
|
||||
const packageInfos: PackageInfo[] = [];
|
||||
const addPackageInfos = (response: SearchResponse) => {
|
||||
for (const object of response.objects) {
|
||||
packageInfos.push(object.package);
|
||||
}
|
||||
};
|
||||
|
||||
const firstResponse = await makeRequest(0);
|
||||
let total = firstResponse.total;
|
||||
addPackageInfos(firstResponse);
|
||||
|
||||
for (let page = 1; packageInfos.length < total; page++) {
|
||||
// Cap the maximum number of requests: Fail early in the case where the search query breaks
|
||||
// in the future.
|
||||
if (page >= 100) {
|
||||
throw new Error('More requests sent than expected. Does maximumRequests need to be increased?');
|
||||
}
|
||||
|
||||
const response = await makeRequest(page * pageSize);
|
||||
total = response.total;
|
||||
addPackageInfos(response);
|
||||
}
|
||||
|
||||
return packageInfos;
|
||||
};
|
||||
|
||||
export default searchPlugins;
|
||||
@@ -30,7 +30,7 @@
|
||||
"devDependencies": {
|
||||
"@types/fs-extra": "11.0.4",
|
||||
"@types/jest": "29.5.14",
|
||||
"@types/node": "18.19.118",
|
||||
"@types/node": "18.19.119",
|
||||
"jest": "29.7.0",
|
||||
"source-map-loader": "5.0.0",
|
||||
"typescript": "5.8.3",
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
"devDependencies": {
|
||||
"@types/jest": "29.5.14",
|
||||
"@types/markdown-it": "13.0.9",
|
||||
"@types/node": "18.19.118",
|
||||
"@types/node": "18.19.119",
|
||||
"jest": "29.7.0",
|
||||
"jest-environment-jsdom": "29.7.0",
|
||||
"mermaid": "11.6.0",
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
"@types/koa": "2.15.0",
|
||||
"@types/markdown-it": "13.0.9",
|
||||
"@types/mustache": "4.2.6",
|
||||
"@types/node": "18.19.118",
|
||||
"@types/node": "18.19.119",
|
||||
"@types/node-os-utils": "1.3.4",
|
||||
"@types/nodemailer": "6.4.17",
|
||||
"@types/yargs": "17.0.33",
|
||||
|
||||
@@ -205,3 +205,8 @@ Pokiesman
|
||||
Gamstop
|
||||
ESIGNER
|
||||
TOTP
|
||||
SPSSO
|
||||
IDPSSO
|
||||
nameid
|
||||
attrname
|
||||
dpkg
|
||||
@@ -52,7 +52,7 @@
|
||||
"@types/js-yaml": "4.0.9",
|
||||
"@types/markdown-it": "13.0.9",
|
||||
"@types/mustache": "4.2.6",
|
||||
"@types/node": "18.19.118",
|
||||
"@types/node": "18.19.119",
|
||||
"@types/node-fetch": "2.6.12",
|
||||
"@types/yargs": "17.0.33",
|
||||
"gettext-extractor": "3.8.0",
|
||||
|
||||
@@ -179,6 +179,7 @@
|
||||
"android-v3.4.6": true,
|
||||
"v3.4.12": true,
|
||||
"android-v3.4.7": true,
|
||||
"ios-v13.4.3": true
|
||||
"ios-v13.4.3": true,
|
||||
"v3.5.4": true
|
||||
}
|
||||
}
|
||||
@@ -2,13 +2,17 @@ import { readFile } from 'fs/promises';
|
||||
import { createTempDir } from './fs.test';
|
||||
import { newHttpError, sendMessage, startServer, stopServer } from './ipc';
|
||||
|
||||
const getRandomPort = () => {
|
||||
return Math.floor(Math.random() * (65535 - 20000 + 1)) + 20000;
|
||||
};
|
||||
|
||||
describe('ipc', () => {
|
||||
|
||||
it('should send and receive messages', async () => {
|
||||
const tempDir = await createTempDir();
|
||||
const secretFilePath = `${tempDir}/secret.txt`;
|
||||
const serverPort1 = 41110;
|
||||
const serverPort2 = 41115;
|
||||
const serverPort1 = getRandomPort();
|
||||
const serverPort2 = serverPort1 + 5;
|
||||
|
||||
const server1 = await startServer(serverPort1, secretFilePath, async (request) => {
|
||||
if (request.action === 'testing') {
|
||||
@@ -87,7 +91,7 @@ describe('ipc', () => {
|
||||
it('should not process message if secret is invalid', async () => {
|
||||
const tempDir = await createTempDir();
|
||||
const secretFilePath = `${tempDir}/secret.txt`;
|
||||
const serverPort = 41120;
|
||||
const serverPort = getRandomPort();
|
||||
|
||||
const server = await startServer(serverPort, secretFilePath, async (request) => {
|
||||
if (request.action === 'testing') {
|
||||
|
||||
@@ -1,5 +1,45 @@
|
||||
# Joplin Desktop Changelog
|
||||
|
||||
## [v3.5.4](https://github.com/laurent22/joplin/releases/tag/v3.5.4) (Pre-release) - 2025-10-10T17:19:58Z
|
||||
|
||||
- New: Add support for mixed case tags ([#12931](https://github.com/laurent22/joplin/issues/12931) by [@mrjo118](https://github.com/mrjo118))
|
||||
- New: Add write() method to Plugin Clipboard API ([#13348](https://github.com/laurent22/joplin/issues/13348) by [@bwat47](https://github.com/bwat47))
|
||||
- Improved: Accessibility: Disable sync icon animation when reduce motion is enabled ([#13283](https://github.com/laurent22/joplin/issues/13283) by [@personalizedrefrigerator](https://github.com/personalizedrefrigerator))
|
||||
- Improved: Add hover + expanded arrow behavior for Notebook/Tags header ([#13190](https://github.com/laurent22/joplin/issues/13190)) ([#12292](https://github.com/laurent22/joplin/issues/12292) by [@maggie897](https://github.com/maggie897))
|
||||
- Improved: Automatically retrigger the sync if there are more unsynced outgoing changes when sync completes ([#12989](https://github.com/laurent22/joplin/issues/12989) by [@mrjo118](https://github.com/mrjo118))
|
||||
- Improved: Avoid excessive data usage when automatically triggering another sync ([#13261](https://github.com/laurent22/joplin/issues/13261) by [@mrjo118](https://github.com/mrjo118))
|
||||
- Improved: Click on systray icon will show/hide Joplin main window ([#13299](https://github.com/laurent22/joplin/issues/13299)) ([#12572](https://github.com/laurent22/joplin/issues/12572) by [@trap000d](https://github.com/trap000d))
|
||||
- Improved: Delete all note revisions when the note is permanently deleted ([#12609](https://github.com/laurent22/joplin/issues/12609)) ([#8718](https://github.com/laurent22/joplin/issues/8718) by [@pedr](https://github.com/pedr))
|
||||
- Improved: Markdown editor search: Auto-scroll to the next match when the search changes ([#13242](https://github.com/laurent22/joplin/issues/13242)) ([#12343](https://github.com/laurent22/joplin/issues/12343) by [@personalizedrefrigerator](https://github.com/personalizedrefrigerator))
|
||||
- Improved: OCR: Fully disable the handwriting transcription backend when disabled in settings ([#13072](https://github.com/laurent22/joplin/issues/13072) by [@personalizedrefrigerator](https://github.com/personalizedrefrigerator))
|
||||
- Improved: OneNote importer: Simplify reporting import issues to the forum ([#13409](https://github.com/laurent22/joplin/issues/13409) by [@personalizedrefrigerator](https://github.com/personalizedrefrigerator))
|
||||
- Improved: Open the Joplin Plugin web page when clicking on a plugin name ([#13376](https://github.com/laurent22/joplin/issues/13376)) ([#13371](https://github.com/laurent22/joplin/issues/13371))
|
||||
- Improved: Prefer user-specified CSS page sizing when printing to PDF ([#13130](https://github.com/laurent22/joplin/issues/13130)) ([#13096](https://github.com/laurent22/joplin/issues/13096) by [@personalizedrefrigerator](https://github.com/personalizedrefrigerator))
|
||||
- Improved: Remove Beta mention for Joplin Server ([#13367](https://github.com/laurent22/joplin/issues/13367))
|
||||
- Improved: Support accepting shares with a new key format ([#12829](https://github.com/laurent22/joplin/issues/12829) by [@personalizedrefrigerator](https://github.com/personalizedrefrigerator))
|
||||
- Improved: Updated packages @axe-core/playwright (v4.10.2), @playwright/test (v1.53.2), @rollup/plugin-commonjs (v28.0.6), form-data (v4.0.3), glob (v11.0.3), react-select (v5.10.2), sass (v1.93.0), sharp (v0.34.3), style-to-js (v1.1.17)
|
||||
- Improved: Upgrade tesseract.js to v6 ([#13345](https://github.com/laurent22/joplin/issues/13345)) ([#12803](https://github.com/laurent22/joplin/issues/12803) by [@personalizedrefrigerator](https://github.com/personalizedrefrigerator))
|
||||
- Improved: Upgrade to Electron 37.4.0 ([#13156](https://github.com/laurent22/joplin/issues/13156) by [@personalizedrefrigerator](https://github.com/personalizedrefrigerator))
|
||||
- Improved: Use plugin repository URL when homepage URL is not available in config screen ([#13318](https://github.com/laurent22/joplin/issues/13318))
|
||||
- Fixed: Accessibility: Fix dismissing the alarm dialog by pressing escape ([#13068](https://github.com/laurent22/joplin/issues/13068)) ([#12816](https://github.com/laurent22/joplin/issues/12816) by [@personalizedrefrigerator](https://github.com/personalizedrefrigerator))
|
||||
- Fixed: Ensure notebook conflicts do not delete child notes and notebooks when resolved ([#13167](https://github.com/laurent22/joplin/issues/13167)) ([#11902](https://github.com/laurent22/joplin/issues/11902) by [@mrjo118](https://github.com/mrjo118))
|
||||
- Fixed: Ensure the sync shows an error when the server is down, when using a local WebDAV server ([#13301](https://github.com/laurent22/joplin/issues/13301) by [@mrjo118](https://github.com/mrjo118))
|
||||
- Fixed: Fix "insecure content security policy" warning ([#13288](https://github.com/laurent22/joplin/issues/13288) by [@personalizedrefrigerator](https://github.com/personalizedrefrigerator))
|
||||
- Fixed: Fix error dialogs fail to appear in certain cases ([#13179](https://github.com/laurent22/joplin/issues/13179) by [@personalizedrefrigerator](https://github.com/personalizedrefrigerator))
|
||||
- Fixed: Fix files without extension not being imported properly ([#12974](https://github.com/laurent22/joplin/issues/12974)) ([#12049](https://github.com/laurent22/joplin/issues/12049) by [@pedr](https://github.com/pedr))
|
||||
- Fixed: Fix historic issue whereby the first revision created for a note does not contain the original contents ([#12674](https://github.com/laurent22/joplin/issues/12674) by [@mrjo118](https://github.com/mrjo118))
|
||||
- Fixed: Fix images rendered in the Markdown editor don't reload when downloaded ([#13045](https://github.com/laurent22/joplin/issues/13045)) ([#12987](https://github.com/laurent22/joplin/issues/12987) by [@personalizedrefrigerator](https://github.com/personalizedrefrigerator))
|
||||
- Fixed: Fix notes are moved to the conflict folder when a folder is unshared ([#12993](https://github.com/laurent22/joplin/issues/12993) by [@personalizedrefrigerator](https://github.com/personalizedrefrigerator))
|
||||
- Fixed: Fix startup error when a non-English locale is selected ([#13347](https://github.com/laurent22/joplin/issues/13347)) ([#13346](https://github.com/laurent22/joplin/issues/13346) by [@personalizedrefrigerator](https://github.com/personalizedrefrigerator))
|
||||
- Fixed: Fix the order of attached images ([#12531](https://github.com/laurent22/joplin/issues/12531)) ([#12868](https://github.com/laurent22/joplin/issues/12868) by [@JZou-Code](https://github.com/JZou-Code))
|
||||
- Fixed: Fixed image load failure when path contains '#' (13267) ([#13375](https://github.com/laurent22/joplin/issues/13375)) ([#13267](https://github.com/laurent22/joplin/issues/13267) by [@yingli-lab](https://github.com/yingli-lab))
|
||||
- Fixed: Fixed red close button not working on macOS 26 ([#13311](https://github.com/laurent22/joplin/issues/13311)) ([#13196](https://github.com/laurent22/joplin/issues/13196) by [@yingli-lab](https://github.com/yingli-lab))
|
||||
- Fixed: Hide 'Start application minimised' unless tray icon is enabled ([#13340](https://github.com/laurent22/joplin/issues/13340)) ([#13088](https://github.com/laurent22/joplin/issues/13088) by [@maggie897](https://github.com/maggie897))
|
||||
- Fixed: Implement the config check for Joplin Server with SAML enabled ([#13360](https://github.com/laurent22/joplin/issues/13360)) ([#13328](https://github.com/laurent22/joplin/issues/13328) by [@ttcchhmm](https://github.com/ttcchhmm))
|
||||
- Fixed: Prevent the default cut action handler to avoid double deletion ([#13208](https://github.com/laurent22/joplin/issues/13208)) ([#12239](https://github.com/laurent22/joplin/issues/12239) by [@JZou-Code](https://github.com/JZou-Code))
|
||||
- Fixed: Skip copy event in TinyMCE if no content is selected. ([#13313](https://github.com/laurent22/joplin/issues/13313)) ([#12763](https://github.com/laurent22/joplin/issues/12763) by [@JZou-Code](https://github.com/JZou-Code))
|
||||
- Fixed: Skip cut action in TinyMCE editor if no content is selected. ([#13315](https://github.com/laurent22/joplin/issues/13315)) ([#13314](https://github.com/laurent22/joplin/issues/13314) by [@JZou-Code](https://github.com/JZou-Code))
|
||||
|
||||
## [v3.4.12](https://github.com/laurent22/joplin/releases/tag/v3.4.12) - 2025-09-09T21:35:47Z
|
||||
|
||||
- Fixed: Fix error when saving in-editor rendering-related settings ([#13105](https://github.com/laurent22/joplin/issues/13105)) ([#13103](https://github.com/laurent22/joplin/issues/13103) by [@personalizedrefrigerator](https://github.com/personalizedrefrigerator))
|
||||
|
||||
@@ -37,7 +37,7 @@ On desktop, the following patterns are replaced:
|
||||
- `$math$`: Auto-formats to inline math (using KaTeX math syntax). After rendering, equations can be edited by double-clicking or with the "edit" option in the right click menu.
|
||||
- `# Heading 1`: Creates a level 1 heading. The `#` should be at the start of the line.
|
||||
- `## Heading 2`: Creates a level 2 heading.
|
||||
- `## Heading 3`: Creates a level 3 heading.
|
||||
- `### Heading 3`: Creates a level 3 heading.
|
||||
- `- List`: Creates a bulleted list.
|
||||
- `1. List`: Creates a numbered list.
|
||||
- `---`, `___`, or `***`: Creates a horizontal rule.
|
||||
|
||||
7
readme/apps/server/ldap.md
Normal file
7
readme/apps/server/ldap.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Joplin Server LDAP support
|
||||
|
||||
Joplin Server supports authentication via LDAP (Lightweight Directory Access Protocol), allowing integration with existing directory services for centralised user management. This enables users to log in using their organisation's credentials, streamlining access control and improving security.
|
||||
|
||||
## Setup
|
||||
|
||||
To enable LDAP, you will need to set the environment variables as defined [in this file](https://github.com/laurent22/joplin/blob/2e846fe15d957873bfa6f16e44ccafc6b31e7a93/packages/server/src/env.ts#L136). You can define up to too LDAP providers.
|
||||
125
readme/apps/server/saml.md
Normal file
125
readme/apps/server/saml.md
Normal file
@@ -0,0 +1,125 @@
|
||||
# Joplin Server SAML support
|
||||
|
||||
Joplin Server supports authentication via SAML (Security Assertion Markup Language), allowing integration with identity providers for single sign-on (SSO). This enables users to log in securely using their existing organisational credentials, simplifying account management and enhancing security.
|
||||
|
||||
## Setup
|
||||
|
||||
To enable SAML, you will need to set the environment variables as defined [in this file](https://github.com/laurent22/joplin/blob/2e846fe15d957873bfa6f16e44ccafc6b31e7a93/packages/server/src/env.ts#L163) and provide a link to your SP and IDP config file.
|
||||
|
||||
An SP file would look like this:
|
||||
|
||||
```xml
|
||||
<?xml version="1.0"?>
|
||||
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="Joplin">
|
||||
<md:SPSSODescriptor AuthnRequestsSigned="false" WantAssertionsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
||||
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat>
|
||||
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
|
||||
Location="http://localhost:22300/api/saml"
|
||||
index="1" />
|
||||
</md:SPSSODescriptor>
|
||||
</md:EntityDescriptor>
|
||||
```
|
||||
|
||||
While and IDP config would look like this:
|
||||
|
||||
<!-- cSpell:disable -->
|
||||
|
||||
```xml
|
||||
<?xml version="1.0"?>
|
||||
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" entityID="saml-idp">
|
||||
<md:IDPSSODescriptor WantAuthnRequestsSigned="false" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
||||
<md:KeyDescriptor use="signing">
|
||||
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
||||
<ds:X509Data>
|
||||
<ds:X509Certificate>MIIDIzCCAgugAwIBAgIUOGfU4onZ0So0R4L4FH2OUo7cmwcwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UEAwwWVGVzdCBJZGVudGl0eSBQcm92aWRlcjAeFw0yNDEwMjUwOTI0NDBaFw00NDEwMjAwOTI0NDBaMCExHzAdBgNVBAMMFlRlc3QgSWRlbnRpdHkgUHJvdmlkZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrgUKiNwsnlCwQViTqUfTKJXtGQdFZ5ZHHupqNX3hLa2H/MqL25k00p9dw3h9ddpnpmvBsP4jaEeXF4ibU/HQ78cWiUzPkQripkTtYvAM2I/KodqyCHPJr0yJtFUCT/rDrtrCRZ1eZ+K1nvzVFBqiQwgY8IOmhVIqvK7r+sOuDoP7fFDbiZgDyD07noA/oMlcfkm/xj5O70YGX+Iqh8FMJTA8z6DyqTQKtXPBhndkchZDehCkWmKsmpvM3X9QBBl71tJoFu9WqGgtvfMWq+/WoTJ18jbcj0p2jhhEuvDsI1jmeisXzwunO0HtmbDgd17rjOP2CIXUffAV+gg7B5PFBAgMBAAGjUzBRMB0GA1UdDgQWBBSDjyS0o+Y8Sjb885BCo+bmvbwrgTAfBgNVHSMEGDAWgBSDjyS0o+Y8Sjb885BCo+bmvbwrgTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAMxqjfHu6rjnm4PeOXywpnRca8Md95tnh0YJNAu9Vb19jpqUF96psS1lZMqmZ66tnLPCi+rBAtI66BO2wClqxe5K9MeiJIZOwDHLqJ8TDGE+8LM/uEOqobtdjp1vSEuLAC2zeXba9ISqYUrXGcTic65EERGBnG3w2D/rTm7te7C0b6yYet1l4K1RqctxDaI90YV2a1aiT1wngaOQclHAJlR7c0kJP6JZaS/R56Y88S0exZo82u4CsI3GuY42M2ET74/5pllsRsYrQz6iXqnrbcpxvFAWj5D+1uq+rdqc8M0dW5CXZ7zLjJxXH9pFneOnSyX6YbuK+b6kdKUxKlQRMs</ds:X509Certificate>
|
||||
</ds:X509Data>
|
||||
</ds:KeyInfo>
|
||||
</md:KeyDescriptor>
|
||||
<md:KeyDescriptor use="encryption">
|
||||
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
||||
<ds:X509Data>
|
||||
<ds:X509Certificate>MIIDIzCCAgugAwIBAgIUOGfU4onZ0So0R4L4FH2OUo7cmwcwDQYJKoZIhvcNAQELBQAwITEfMB0GA1UEAwwWVGVzdCBJZGVudGl0eSBQcm92aWRlcjAeFw0yNDEwMjUwOTI0NDBaFw00NDEwMjAwOTI0NDBaMCExHzAdBgNVBAMMFlRlc3QgSWRlbnRpdHkgUHJvdmlkZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrgUKiNwsnlCwQViTqUfTKJXtGQdFZ5ZHHupqNX3hLa2H/MqL25k00p9dw3h9ddpnpmvBsP4jaEeXF4ibU/HQ78cWiUzPkQripkTtYvAM2I/KodqyCHPJr0yJtFUCT/rDrtrCRZ1eZ+K1nvzVFBqiQwgY8IOmhVIqvK7r+sOuDoP7fFDbiZgDyD07noA/oMlcfkm/xj5O70YGX+Iqh8FMJTA8z6DyqTQKtXPBhndkchZDehCkWmKsmpvM3X9QBBl71tJoFu9WqGgtvfMWq+/WoTJ18jbcj0p2jhhEuvDsI1jmeisXzwunO0HtmbDgd17rjOP2CIXUffAV+gg7B5PFBAgMBAAGjUzBRMB0GA1UdDgQWBBSDjyS0o+Y8Sjb885BCo+bmvbwrgTAfBgNVHSMEGDAWgBSDjyS0o+Y8Sjb885BCo+bmvbwrgTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAMxqjfHu6rjnm4PeOXywpnRca8Md95tnh0YJNAu9Vb19jpqUF96psS1lZMqmZ66tnLPCi+rBAtI66BO2wClqxe5K9MeiJIZOwDHLqJ8TDGE+8LM/uEOqobtdjp1vSEuLAC2zeXba9ISqYUrXGcTic65EERGBnG3w2D/rTm7te7C0b6yYet1l4K1RqctxDaI90YV2a1aiT1wngaOQclHAJlR7c0kJP6JZaS/R56Y88S0exZo82u4CsI3GuY42M2ET74/5pllsRsYrQz6iXqnrbcpxvFAWj5D+1uq+rdqc8M0dW5CXZ7zLjJxXH9pFneOnSyX6YbuK+b6kdKUxKlQRMs</ds:X509Certificate>
|
||||
</ds:X509Data>
|
||||
</ds:KeyInfo>
|
||||
</md:KeyDescriptor>
|
||||
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat>
|
||||
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</NameIDFormat>
|
||||
<NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</NameIDFormat>
|
||||
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="http://localhost:7000/saml/sso"/>
|
||||
<SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://localhost:7000/saml/sso"/>
|
||||
<Attribute Name="firstName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="First Name" xmlns="urn:oasis:names:tc:SAML:2.0:assertion"/>
|
||||
<Attribute Name="lastName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="Last Name" xmlns="urn:oasis:names:tc:SAML:2.0:assertion"/>
|
||||
<Attribute Name="displayName" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="Display Name" xmlns="urn:oasis:names:tc:SAML:2.0:assertion"/>
|
||||
<Attribute Name="email" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="E-Mail Address" xmlns="urn:oasis:names:tc:SAML:2.0:assertion"/>
|
||||
<Attribute Name="mobilePhone" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="Mobile Phone" xmlns="urn:oasis:names:tc:SAML:2.0:assertion"/>
|
||||
<Attribute Name="groups" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="Groups" xmlns="urn:oasis:names:tc:SAML:2.0:assertion"/>
|
||||
<Attribute Name="userType" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" FriendlyName="User Type" xmlns="urn:oasis:names:tc:SAML:2.0:assertion"/>
|
||||
</md:IDPSSODescriptor>
|
||||
</md:EntityDescriptor>
|
||||
```
|
||||
|
||||
<!-- cSpell:enable -->
|
||||
|
||||
## Required user attributes
|
||||
|
||||
Users must have the following attributes configured on your SAML provider:
|
||||
|
||||
- `email`: The user email.
|
||||
- `displayName`: The user full name.
|
||||
|
||||
## Custom CA certificates
|
||||
|
||||
By default, the Joplin Server image does not include the `ca-certificates` which may be needed to get custom certificates for your mail server working. You can install those additional packages (and any other package), using the method below:
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml
|
||||
|
||||
services:
|
||||
|
||||
joplin-server:
|
||||
image: path/to/image
|
||||
ports:
|
||||
- "80:80"
|
||||
env_file: .env
|
||||
volumes:
|
||||
- ./config/data:/data:rw
|
||||
- ./config/saml:/saml:ro
|
||||
- ./config/certs:/tmp/certs:ro
|
||||
user: root
|
||||
command: >
|
||||
bash -c '
|
||||
# Install the missing packages
|
||||
|
||||
if ! dpkg -s ca-certificates >/dev/null 2>&1; then
|
||||
apt update &&
|
||||
apt install -y ca-certificates openssl
|
||||
fi
|
||||
|
||||
# Create the CA folder if necessary
|
||||
|
||||
mkdir -p /usr/local/share/ca-certificates
|
||||
|
||||
# Copy the certificates only if modified
|
||||
|
||||
changed=false
|
||||
for cert in /tmp/certs/*.crt; do
|
||||
if [ -f "$cert" ]; then
|
||||
target=/usr/local/share/ca-certificates/$(basename "$cert")
|
||||
if [ ! -f "$target" ] || ! cmp -s "$cert" "$target"; then
|
||||
cp "$cert" "$target"
|
||||
changed=true
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Update the CA only if necessary
|
||||
|
||||
if [ "$changed" = true ]; then
|
||||
update-ca-certificates
|
||||
fi
|
||||
|
||||
# Launch the server
|
||||
|
||||
tini -- yarn start-server
|
||||
'
|
||||
```
|
||||
@@ -22,7 +22,7 @@ Please note that there cannot be more than 400 (maybe 500) words in those lists.
|
||||
|
||||
### Using comments
|
||||
|
||||
You can ignore a block of code by wrapping it in `// cSpell:disable` / `// cSpell:enable`.
|
||||
You can ignore a block of code by wrapping it in `// cSpell:disable` / `// cSpell:enable` in JS/TS files, or in `<!-- cSpell:enable -->` / `<!-- cSpell:disable -->` in Markdown files.
|
||||
|
||||
Only do this when there's a large block of code that contains many words to be ignored. Otherwise prefer the word list because it means we don't pollute the code with additional comments.
|
||||
|
||||
|
||||
179
yarn.lock
179
yarn.lock
@@ -9158,7 +9158,7 @@ __metadata:
|
||||
"@testing-library/react-hooks": "npm:8.0.1"
|
||||
"@types/jest": "npm:29.5.14"
|
||||
"@types/mustache": "npm:4.2.6"
|
||||
"@types/node": "npm:18.19.118"
|
||||
"@types/node": "npm:18.19.119"
|
||||
"@types/react": "npm:18.3.23"
|
||||
"@types/react-dom": "npm:18.3.7"
|
||||
"@types/react-redux": "npm:7.1.33"
|
||||
@@ -9250,17 +9250,17 @@ __metadata:
|
||||
"@react-native-community/netinfo": "npm:11.4.1"
|
||||
"@react-native-community/push-notification-ios": "npm:1.11.0"
|
||||
"@react-native-documents/picker": "npm:10.1.5"
|
||||
"@react-native/babel-preset": "npm:0.79.5"
|
||||
"@react-native/babel-preset": "npm:0.80.1"
|
||||
"@react-native/metro-config": "npm:0.79.5"
|
||||
"@react-native/typescript-config": "npm:0.79.5"
|
||||
"@sqlite.org/sqlite-wasm": "npm:3.46.0-build2"
|
||||
"@testing-library/react-native": "npm:13.2.0"
|
||||
"@types/fs-extra": "npm:11.0.4"
|
||||
"@types/jest": "npm:29.5.14"
|
||||
"@types/node": "npm:18.19.118"
|
||||
"@types/node": "npm:18.19.119"
|
||||
"@types/react": "npm:19.0.14"
|
||||
"@types/react-redux": "npm:7.1.33"
|
||||
"@types/serviceworker": "npm:0.0.141"
|
||||
"@types/serviceworker": "npm:0.0.142"
|
||||
"@types/tar-stream": "npm:3.1.4"
|
||||
assert-browserify: "npm:2.0.0"
|
||||
babel-jest: "npm:29.7.0"
|
||||
@@ -9274,9 +9274,9 @@ __metadata:
|
||||
deprecated-react-native-prop-types: "npm:5.0.0"
|
||||
esbuild: "npm:0.25.6"
|
||||
events: "npm:3.3.0"
|
||||
expo: "npm:53.0.19"
|
||||
expo: "npm:53.0.20"
|
||||
expo-av: "npm:15.1.7"
|
||||
expo-camera: "npm:16.1.10"
|
||||
expo-camera: "npm:16.1.11"
|
||||
expo-local-authentication: "npm:16.0.5"
|
||||
fast-deep-equal: "npm:3.1.3"
|
||||
fs-extra: "npm:11.2.0"
|
||||
@@ -9405,7 +9405,7 @@ __metadata:
|
||||
"@replit/codemirror-vim": "npm:6.2.1"
|
||||
"@testing-library/react-hooks": "npm:8.0.1"
|
||||
"@types/jest": "npm:29.5.14"
|
||||
"@types/node": "npm:18.19.118"
|
||||
"@types/node": "npm:18.19.119"
|
||||
"@types/react": "npm:18.3.23"
|
||||
"@types/react-redux": "npm:7.1.33"
|
||||
"@types/styled-components": "npm:5.1.32"
|
||||
@@ -9437,7 +9437,7 @@ __metadata:
|
||||
resolution: "@joplin/fork-htmlparser2@workspace:packages/fork-htmlparser2"
|
||||
dependencies:
|
||||
"@types/jest": "npm:29.5.14"
|
||||
"@types/node": "npm:18.19.118"
|
||||
"@types/node": "npm:18.19.119"
|
||||
"@typescript-eslint/eslint-plugin": "npm:6.21.0"
|
||||
"@typescript-eslint/parser": "npm:6.21.0"
|
||||
coveralls: "npm:3.1.1"
|
||||
@@ -9467,7 +9467,7 @@ __metadata:
|
||||
resolution: "@joplin/fork-uslug@workspace:packages/fork-uslug"
|
||||
dependencies:
|
||||
"@types/jest": "npm:29.5.14"
|
||||
"@types/node": "npm:18.19.118"
|
||||
"@types/node": "npm:18.19.119"
|
||||
jest: "npm:29.7.0"
|
||||
node-emoji: "npm:1.11.0"
|
||||
typescript: "npm:5.8.3"
|
||||
@@ -9516,7 +9516,7 @@ __metadata:
|
||||
"@types/markdown-it": "npm:13.0.9"
|
||||
"@types/mustache": "npm:4.2.6"
|
||||
"@types/nanoid": "npm:3.0.0"
|
||||
"@types/node": "npm:18.19.118"
|
||||
"@types/node": "npm:18.19.119"
|
||||
"@types/node-rsa": "npm:1.1.4"
|
||||
"@types/react": "npm:18.3.23"
|
||||
"@types/uuid": "npm:10.0.0"
|
||||
@@ -9534,7 +9534,7 @@ __metadata:
|
||||
fast-xml-parser: "npm:3.21.1"
|
||||
file-type: "npm:16.5.4"
|
||||
follow-redirects: "npm:1.15.6"
|
||||
form-data: "npm:4.0.3"
|
||||
form-data: "npm:4.0.4"
|
||||
fs-extra: "npm:11.2.0"
|
||||
hpagent: "npm:1.2.0"
|
||||
html-entities: "npm:1.4.0"
|
||||
@@ -9632,7 +9632,7 @@ __metadata:
|
||||
"@joplin/utils": "npm:~3.5"
|
||||
"@types/fs-extra": "npm:11.0.4"
|
||||
"@types/jest": "npm:29.5.14"
|
||||
"@types/node": "npm:18.19.118"
|
||||
"@types/node": "npm:18.19.119"
|
||||
fs-extra: "npm:11.2.0"
|
||||
gh-release-assets: "npm:2.0.1"
|
||||
jest: "npm:29.7.0"
|
||||
@@ -9687,7 +9687,7 @@ __metadata:
|
||||
"@joplin/utils": "npm:~3.5"
|
||||
"@types/jest": "npm:29.5.14"
|
||||
"@types/markdown-it": "npm:13.0.9"
|
||||
"@types/node": "npm:18.19.118"
|
||||
"@types/node": "npm:18.19.119"
|
||||
font-awesome-filetypes: "npm:2.1.0"
|
||||
fs-extra: "npm:11.2.0"
|
||||
highlight.js: "npm:11.11.1"
|
||||
@@ -9738,7 +9738,7 @@ __metadata:
|
||||
"@types/koa": "npm:2.15.0"
|
||||
"@types/markdown-it": "npm:13.0.9"
|
||||
"@types/mustache": "npm:4.2.6"
|
||||
"@types/node": "npm:18.19.118"
|
||||
"@types/node": "npm:18.19.119"
|
||||
"@types/node-os-utils": "npm:1.3.4"
|
||||
"@types/nodemailer": "npm:6.4.17"
|
||||
"@types/uuid": "npm:10.0.0"
|
||||
@@ -9798,7 +9798,7 @@ __metadata:
|
||||
"@types/js-yaml": "npm:4.0.9"
|
||||
"@types/markdown-it": "npm:13.0.9"
|
||||
"@types/mustache": "npm:4.2.6"
|
||||
"@types/node": "npm:18.19.118"
|
||||
"@types/node": "npm:18.19.119"
|
||||
"@types/node-fetch": "npm:2.6.12"
|
||||
"@types/yargs": "npm:17.0.33"
|
||||
compare-versions: "npm:6.1.1"
|
||||
@@ -12336,6 +12336,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-native/babel-plugin-codegen@npm:0.80.1":
|
||||
version: 0.80.1
|
||||
resolution: "@react-native/babel-plugin-codegen@npm:0.80.1"
|
||||
dependencies:
|
||||
"@babel/traverse": "npm:^7.25.3"
|
||||
"@react-native/codegen": "npm:0.80.1"
|
||||
checksum: 10/42843a8b3fd4f469f60f9b23a3f3b7820d9520df0a495d878e907bd5548c7155ce65482de6c120351f50b2cd7c8373a08625efc9cc0bc3de56e0a83b9cfece08
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-native/babel-preset@npm:0.79.5":
|
||||
version: 0.79.5
|
||||
resolution: "@react-native/babel-preset@npm:0.79.5"
|
||||
@@ -12391,6 +12401,61 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-native/babel-preset@npm:0.80.1":
|
||||
version: 0.80.1
|
||||
resolution: "@react-native/babel-preset@npm:0.80.1"
|
||||
dependencies:
|
||||
"@babel/core": "npm:^7.25.2"
|
||||
"@babel/plugin-proposal-export-default-from": "npm:^7.24.7"
|
||||
"@babel/plugin-syntax-dynamic-import": "npm:^7.8.3"
|
||||
"@babel/plugin-syntax-export-default-from": "npm:^7.24.7"
|
||||
"@babel/plugin-syntax-nullish-coalescing-operator": "npm:^7.8.3"
|
||||
"@babel/plugin-syntax-optional-chaining": "npm:^7.8.3"
|
||||
"@babel/plugin-transform-arrow-functions": "npm:^7.24.7"
|
||||
"@babel/plugin-transform-async-generator-functions": "npm:^7.25.4"
|
||||
"@babel/plugin-transform-async-to-generator": "npm:^7.24.7"
|
||||
"@babel/plugin-transform-block-scoping": "npm:^7.25.0"
|
||||
"@babel/plugin-transform-class-properties": "npm:^7.25.4"
|
||||
"@babel/plugin-transform-classes": "npm:^7.25.4"
|
||||
"@babel/plugin-transform-computed-properties": "npm:^7.24.7"
|
||||
"@babel/plugin-transform-destructuring": "npm:^7.24.8"
|
||||
"@babel/plugin-transform-flow-strip-types": "npm:^7.25.2"
|
||||
"@babel/plugin-transform-for-of": "npm:^7.24.7"
|
||||
"@babel/plugin-transform-function-name": "npm:^7.25.1"
|
||||
"@babel/plugin-transform-literals": "npm:^7.25.2"
|
||||
"@babel/plugin-transform-logical-assignment-operators": "npm:^7.24.7"
|
||||
"@babel/plugin-transform-modules-commonjs": "npm:^7.24.8"
|
||||
"@babel/plugin-transform-named-capturing-groups-regex": "npm:^7.24.7"
|
||||
"@babel/plugin-transform-nullish-coalescing-operator": "npm:^7.24.7"
|
||||
"@babel/plugin-transform-numeric-separator": "npm:^7.24.7"
|
||||
"@babel/plugin-transform-object-rest-spread": "npm:^7.24.7"
|
||||
"@babel/plugin-transform-optional-catch-binding": "npm:^7.24.7"
|
||||
"@babel/plugin-transform-optional-chaining": "npm:^7.24.8"
|
||||
"@babel/plugin-transform-parameters": "npm:^7.24.7"
|
||||
"@babel/plugin-transform-private-methods": "npm:^7.24.7"
|
||||
"@babel/plugin-transform-private-property-in-object": "npm:^7.24.7"
|
||||
"@babel/plugin-transform-react-display-name": "npm:^7.24.7"
|
||||
"@babel/plugin-transform-react-jsx": "npm:^7.25.2"
|
||||
"@babel/plugin-transform-react-jsx-self": "npm:^7.24.7"
|
||||
"@babel/plugin-transform-react-jsx-source": "npm:^7.24.7"
|
||||
"@babel/plugin-transform-regenerator": "npm:^7.24.7"
|
||||
"@babel/plugin-transform-runtime": "npm:^7.24.7"
|
||||
"@babel/plugin-transform-shorthand-properties": "npm:^7.24.7"
|
||||
"@babel/plugin-transform-spread": "npm:^7.24.7"
|
||||
"@babel/plugin-transform-sticky-regex": "npm:^7.24.7"
|
||||
"@babel/plugin-transform-typescript": "npm:^7.25.2"
|
||||
"@babel/plugin-transform-unicode-regex": "npm:^7.24.7"
|
||||
"@babel/template": "npm:^7.25.0"
|
||||
"@react-native/babel-plugin-codegen": "npm:0.80.1"
|
||||
babel-plugin-syntax-hermes-parser: "npm:0.28.1"
|
||||
babel-plugin-transform-flow-enums: "npm:^0.0.2"
|
||||
react-refresh: "npm:^0.14.0"
|
||||
peerDependencies:
|
||||
"@babel/core": "*"
|
||||
checksum: 10/c922b0a90294724d1c5056edf5473ba52c7b42b82d31995d913f69c4f8c163a9bc25bebdcf84af88ab4ca2135d9a46617a55005d73fa54254e5bc45878f022b1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-native/codegen@npm:0.79.2":
|
||||
version: 0.79.2
|
||||
resolution: "@react-native/codegen@npm:0.79.2"
|
||||
@@ -12421,6 +12486,21 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-native/codegen@npm:0.80.1":
|
||||
version: 0.80.1
|
||||
resolution: "@react-native/codegen@npm:0.80.1"
|
||||
dependencies:
|
||||
glob: "npm:^7.1.1"
|
||||
hermes-parser: "npm:0.28.1"
|
||||
invariant: "npm:^2.2.4"
|
||||
nullthrows: "npm:^1.1.1"
|
||||
yargs: "npm:^17.6.2"
|
||||
peerDependencies:
|
||||
"@babel/core": "*"
|
||||
checksum: 10/cd568b3721b4d52797f7eb8acfff17832db376e4b54299bf15c7db840e8e1ea7e525c7d2e58da0d3775360507ea1070a1a5f909829ed5a0fcebb88bcce8018c7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@react-native/community-cli-plugin@npm:0.79.2":
|
||||
version: 0.79.2
|
||||
resolution: "@react-native/community-cli-plugin@npm:0.79.2"
|
||||
@@ -14514,12 +14594,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/node@npm:18.19.118":
|
||||
version: 18.19.118
|
||||
resolution: "@types/node@npm:18.19.118"
|
||||
"@types/node@npm:18.19.119":
|
||||
version: 18.19.119
|
||||
resolution: "@types/node@npm:18.19.119"
|
||||
dependencies:
|
||||
undici-types: "npm:~5.26.4"
|
||||
checksum: 10/ed7a7ef22b10f463ea168f0d9a354902b1cc3af7d8df94cbbd986a60c504afab7d184ea6bf9fd2125d8e800d076f60171bb593567014a54dbf83d1645819234d
|
||||
checksum: 10/d41d94e575611f0d94498e1c91fc06f4f448dd4b1e952fc8812b69b1e549874a18d510334b6e88d65d5a8ac77de07bf21e2637b297f49d80319204c43aa9fa59
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -14850,10 +14930,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/serviceworker@npm:0.0.141":
|
||||
version: 0.0.141
|
||||
resolution: "@types/serviceworker@npm:0.0.141"
|
||||
checksum: 10/e4f8a77dbdefdc87d06b56ef571ae5c6fe222022dfdcdea5502f18b1cdb1732be19d8f0a2a50eb4875aef1252687928881812df15cdf4dd12cb9efa6b06e5d4c
|
||||
"@types/serviceworker@npm:0.0.142":
|
||||
version: 0.0.142
|
||||
resolution: "@types/serviceworker@npm:0.0.142"
|
||||
checksum: 10/f0671243a0b91fdf66a63e1793b4d604329dbabca608c8d1e3915f03d0d315afbe97e761e575eb5327ebf0c9934c6077733e7607f8e15255b3958d4955fee044
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -17687,13 +17767,13 @@ __metadata:
|
||||
linkType: hard
|
||||
|
||||
"axios@npm:^1.7.7":
|
||||
version: 1.9.0
|
||||
resolution: "axios@npm:1.9.0"
|
||||
version: 1.12.2
|
||||
resolution: "axios@npm:1.12.2"
|
||||
dependencies:
|
||||
follow-redirects: "npm:^1.15.6"
|
||||
form-data: "npm:^4.0.0"
|
||||
form-data: "npm:^4.0.4"
|
||||
proxy-from-env: "npm:^1.1.0"
|
||||
checksum: 10/a2f90bba56820883879f32a237e2b9ff25c250365dcafd41cec41b3406a3df334a148f90010182dfdadb4b41dc59f6f0b3e8898ff41b666d1157b5f3f4523497
|
||||
checksum: 10/886a79770594eaad76493fecf90344b567bd956240609b5dcd09bd0afe8d3e6f1ad6d3257a93a483b6192b409d4b673d9515a34619e3e3ed1b2c0ec2a83b20ba
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -18004,6 +18084,15 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"babel-plugin-syntax-hermes-parser@npm:0.28.1":
|
||||
version: 0.28.1
|
||||
resolution: "babel-plugin-syntax-hermes-parser@npm:0.28.1"
|
||||
dependencies:
|
||||
hermes-parser: "npm:0.28.1"
|
||||
checksum: 10/2cbc921e663463480ead9ccc8bb229a5196032367ba2b5ccb18a44faa3afa84b4dc493297749983b9a837a3d76b0b123664aecc06f9122618c3246f03e076a9d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"babel-plugin-syntax-jsx@npm:^6.18.0":
|
||||
version: 6.18.0
|
||||
resolution: "babel-plugin-syntax-jsx@npm:6.18.0"
|
||||
@@ -26133,9 +26222,9 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"expo-camera@npm:16.1.10":
|
||||
version: 16.1.10
|
||||
resolution: "expo-camera@npm:16.1.10"
|
||||
"expo-camera@npm:16.1.11":
|
||||
version: 16.1.11
|
||||
resolution: "expo-camera@npm:16.1.11"
|
||||
dependencies:
|
||||
invariant: "npm:^2.2.4"
|
||||
peerDependencies:
|
||||
@@ -26146,7 +26235,7 @@ __metadata:
|
||||
peerDependenciesMeta:
|
||||
react-native-web:
|
||||
optional: true
|
||||
checksum: 10/40cabe31c6567fe4e97aa9420a7958a0103bb35a9563c70a27052a1674aba3c2e21ec9605df7d77e6fe9af49adafe0d09a71b2513c8ae8e1e4a347ab21cbacbb
|
||||
checksum: 10/8e44f73a4239b52ba9a5784288d3d2c1d53882b85afad0b75947984929f9a25cea997c99e44e81751122c8b1fd7e65dccd43c3609065c5944067ce6ba50a71f0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -26223,18 +26312,18 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"expo-modules-core@npm:2.4.2":
|
||||
version: 2.4.2
|
||||
resolution: "expo-modules-core@npm:2.4.2"
|
||||
"expo-modules-core@npm:2.5.0":
|
||||
version: 2.5.0
|
||||
resolution: "expo-modules-core@npm:2.5.0"
|
||||
dependencies:
|
||||
invariant: "npm:^2.2.4"
|
||||
checksum: 10/c8992dcd7e9a3124c245beb65333add2c1955200724ac5b0a3fc5214f8da2b7779f6f88474b284be5dc9bc4030369c2189ea14200b97854758e086c0ee10c6bf
|
||||
checksum: 10/ad34d71571bcfbff166da47fa3847ab03886b691b80079d9a3d111e5061cccbaa785c55eb48451ce7d300ce725d32f844492b0109d069dc89f70864b9de2c1c6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"expo@npm:53.0.19":
|
||||
version: 53.0.19
|
||||
resolution: "expo@npm:53.0.19"
|
||||
"expo@npm:53.0.20":
|
||||
version: 53.0.20
|
||||
resolution: "expo@npm:53.0.20"
|
||||
dependencies:
|
||||
"@babel/runtime": "npm:^7.20.0"
|
||||
"@expo/cli": "npm:0.24.20"
|
||||
@@ -26250,7 +26339,7 @@ __metadata:
|
||||
expo-font: "npm:~13.3.2"
|
||||
expo-keep-awake: "npm:~14.1.4"
|
||||
expo-modules-autolinking: "npm:2.1.14"
|
||||
expo-modules-core: "npm:2.4.2"
|
||||
expo-modules-core: "npm:2.5.0"
|
||||
react-native-edge-to-edge: "npm:1.6.0"
|
||||
whatwg-url-without-unicode: "npm:8.0.0-3"
|
||||
peerDependencies:
|
||||
@@ -26270,7 +26359,7 @@ __metadata:
|
||||
expo: bin/cli
|
||||
expo-modules-autolinking: bin/autolinking
|
||||
fingerprint: bin/fingerprint
|
||||
checksum: 10/e48538498158176e2af9ed3105cd7547f47dffd50045c3ac8d61181cd93cafc44d56107e7bfdcc0de849ce44b0155fd91949989151805d03ae4ad6c2e66c7561
|
||||
checksum: 10/73cb5ad2e3eb8927390ff685b3f53b0a496fdaa99ec73f6cc3faa732534ad5ec0b5378abdf3da2d0c692397b758eadeed1eabad7f412f0b7576c29f2518e6f93
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -27318,16 +27407,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"form-data@npm:4.0.3":
|
||||
version: 4.0.3
|
||||
resolution: "form-data@npm:4.0.3"
|
||||
"form-data@npm:4.0.4, form-data@npm:^4.0.4":
|
||||
version: 4.0.4
|
||||
resolution: "form-data@npm:4.0.4"
|
||||
dependencies:
|
||||
asynckit: "npm:^0.4.0"
|
||||
combined-stream: "npm:^1.0.8"
|
||||
es-set-tostringtag: "npm:^2.1.0"
|
||||
hasown: "npm:^2.0.2"
|
||||
mime-types: "npm:^2.1.12"
|
||||
checksum: 10/22f6e55e6f32a5797a500ed7ca5aa9d690c4de6e1b3308f25f0d83a27d08d91a265ab59a190db2305b15144f8f07df08e8117bad6a93fc93de1baa838bfcc0b5
|
||||
checksum: 10/a4b62e21932f48702bc468cc26fb276d186e6b07b557e3dd7cc455872bdbb82db7db066844a64ad3cf40eaf3a753c830538183570462d3649fdfd705601cbcfb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@@ -32695,7 +32784,7 @@ __metadata:
|
||||
"@joplin/utils": "npm:~3.5"
|
||||
"@types/fs-extra": "npm:11.0.4"
|
||||
"@types/jest": "npm:29.5.14"
|
||||
"@types/node": "npm:18.19.118"
|
||||
"@types/node": "npm:18.19.119"
|
||||
"@types/proper-lockfile": "npm:^4.1.2"
|
||||
aws-sdk: "npm:2.1340.0"
|
||||
chalk: "npm:4.1.2"
|
||||
|
||||
Reference in New Issue
Block a user