orgnote-api 0.41.13 → 0.41.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/api.d.ts +2 -1
- package/constants/i18n-keys.d.ts +10 -4
- package/constants/i18n-keys.js +4 -1
- package/encryption/encryption.d.ts +10 -0
- package/encryption/encryption.js +38 -28
- package/models/default-commands.d.ts +3 -0
- package/models/default-commands.js +4 -0
- package/models/encryption.d.ts +17 -4
- package/models/encryption.js +13 -4
- package/models/file-content.d.ts +5 -0
- package/models/file-content.js +1 -0
- package/models/index.d.ts +1 -0
- package/models/index.js +1 -0
- package/models/modal.d.ts +1 -0
- package/models/orgnote-config.d.ts +8 -2
- package/package.json +1 -1
- package/utils/__tests__/is-gpg-encrypted.spec.js +27 -1
- package/utils/is-gpg-encrypted.d.ts +1 -0
- package/utils/is-gpg-encrypted.js +8 -0
package/api.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { InlineEmbeddedWidget, MultilineEmbeddedWidget, OrgLineClass, SyncStoreDefinition, BufferViewerStoreDefinition, CommandsStoreDefinition, CommandsGroupStoreDefinition, ModalStoreDefinition, SettingsStoreDefinition, SettingsUiStoreDefinition, MultipleUploadParams, UploadParams, CompletionStoreDefinition, PaneStoreDefinition, LayoutStoreDefinition, FileManagerStoreDefinition, UseScreenDetection, UseKeyboardState, NotificationsStoreDefinition, BufferStoreDefinition, BufferProviderStoreDefinition, Repositories, LogStoreDefinition, UseSystemInfo, ContextMenuStoreDefinition, QueueStoreDefinition, FileGuardStoreDefinition, FileWatcherStoreDefinition, BuildOrgNoteUrl, AuthStoreDefinition, FileSearchStoreDefinition, FileMetaStoreDefinition, FontStoreDefinition, EmbeddedBufferStoreDefinition } from './models/index.js';
|
|
1
|
+
import { InlineEmbeddedWidget, MultilineEmbeddedWidget, OrgLineClass, SyncStoreDefinition, BufferViewerStoreDefinition, CommandsStoreDefinition, CommandsGroupStoreDefinition, ModalStoreDefinition, SettingsStoreDefinition, SettingsUiStoreDefinition, MultipleUploadParams, UploadParams, CompletionStoreDefinition, PaneStoreDefinition, LayoutStoreDefinition, FileManagerStoreDefinition, UseScreenDetection, UseKeyboardState, NotificationsStoreDefinition, BufferStoreDefinition, BufferProviderStoreDefinition, Repositories, LogStoreDefinition, UseSystemInfo, ContextMenuStoreDefinition, QueueStoreDefinition, FileGuardStoreDefinition, FileWatcherStoreDefinition, BuildOrgNoteUrl, AuthStoreDefinition, FileSearchStoreDefinition, FileMetaStoreDefinition, FontStoreDefinition, EmbeddedBufferStoreDefinition, UseFileContent } from './models/index.js';
|
|
2
2
|
import { WebSocketClient } from './websocket/client.js';
|
|
3
3
|
import { WidgetType } from './models/widget-type.js';
|
|
4
4
|
import { NodeType } from 'org-mode-ast';
|
|
@@ -76,6 +76,7 @@ export interface OrgNoteApi {
|
|
|
76
76
|
useFileSearch: FileSearchStoreDefinition;
|
|
77
77
|
useFileMeta: FileMetaStoreDefinition;
|
|
78
78
|
useEmbeddedBuffer: EmbeddedBufferStoreDefinition;
|
|
79
|
+
useFileContent: UseFileContent;
|
|
79
80
|
app: App;
|
|
80
81
|
};
|
|
81
82
|
utils: {
|
package/constants/i18n-keys.d.ts
CHANGED
|
@@ -37,7 +37,7 @@ export declare enum i18n {
|
|
|
37
37
|
GPG_PRIVATE_KEY = "GPG private key",
|
|
38
38
|
ENCRYPT_EXISTING_NOTES = "encrypt existing notes",
|
|
39
39
|
ENCRYPTION_KEYS_GEN_WARNING = "be careful, the old encryption keys will be lost. Third-party clients will need to update encryption keys.",
|
|
40
|
-
|
|
40
|
+
ENCRYPTED_NOTES_KEY_CHANGE_WARNING = "you have encrypted notes. Changing encryption keys will make them unreadable unless you re-encrypt them manually. Continue?",
|
|
41
41
|
SYNC_FILES = "sync files",
|
|
42
42
|
SYNC_FILES_DESCRIPTION = "synchronize all local files with the remote server",
|
|
43
43
|
GENERATE_GPG_KEYS = "generate new GPG keys",
|
|
@@ -163,7 +163,9 @@ export declare enum i18n {
|
|
|
163
163
|
TOC_NO_HEADLINES_FOUND = "no headlines found",
|
|
164
164
|
PICK_NOTE_TO_LINK = "pick note to link",
|
|
165
165
|
UNTITLED = "untitled",
|
|
166
|
-
NO_SELECTED_NOTE = "no selected note"
|
|
166
|
+
NO_SELECTED_NOTE = "no selected note",
|
|
167
|
+
GPG_EMAIL_REQUIRED = "gpg email required",
|
|
168
|
+
GPG_EMAIL_INVALID = "gpg email invalid"
|
|
167
169
|
}
|
|
168
170
|
export declare const I18N: {
|
|
169
171
|
REPORT_BUG: DefaultCommands.REPORT_BUG;
|
|
@@ -226,6 +228,9 @@ export declare const I18N: {
|
|
|
226
228
|
RELOAD_FILES: DefaultCommands.RELOAD_FILES;
|
|
227
229
|
ENCRYPT_NOTE: DefaultCommands.ENCRYPT_NOTE;
|
|
228
230
|
DECRYPT_NOTE: DefaultCommands.DECRYPT_NOTE;
|
|
231
|
+
UPLOAD_PRIVATE_KEY: DefaultCommands.UPLOAD_PRIVATE_KEY;
|
|
232
|
+
UPLOAD_PUBLIC_KEY: DefaultCommands.UPLOAD_PUBLIC_KEY;
|
|
233
|
+
GENERATE_GPG_KEYS: DefaultCommands.GENERATE_GPG_KEYS;
|
|
229
234
|
MAXIMIZE_FILE_MANAGER: DefaultCommands.MAXIMIZE_FILE_MANAGER;
|
|
230
235
|
CREATE_FOLDER: DefaultCommands.CREATE_FOLDER;
|
|
231
236
|
CREATE_FILE: DefaultCommands.CREATE_FILE;
|
|
@@ -318,9 +323,8 @@ export declare const I18N: {
|
|
|
318
323
|
GPG_PRIVATE_KEY: i18n.GPG_PRIVATE_KEY;
|
|
319
324
|
ENCRYPT_EXISTING_NOTES: i18n.ENCRYPT_EXISTING_NOTES;
|
|
320
325
|
ENCRYPTION_KEYS_GEN_WARNING: i18n.ENCRYPTION_KEYS_GEN_WARNING;
|
|
321
|
-
|
|
326
|
+
ENCRYPTED_NOTES_KEY_CHANGE_WARNING: i18n.ENCRYPTED_NOTES_KEY_CHANGE_WARNING;
|
|
322
327
|
SYNC_FILES_DESCRIPTION: i18n.SYNC_FILES_DESCRIPTION;
|
|
323
|
-
GENERATE_GPG_KEYS: i18n.GENERATE_GPG_KEYS;
|
|
324
328
|
UPLOAD: i18n.UPLOAD;
|
|
325
329
|
AVAILABLE_FOR_SUBSCRIPTION: i18n.AVAILABLE_FOR_SUBSCRIPTION;
|
|
326
330
|
SUCCESSFULLY_SUBSCRIBED: i18n.SUCCESSFULLY_SUBSCRIBED;
|
|
@@ -439,5 +443,7 @@ export declare const I18N: {
|
|
|
439
443
|
PICK_NOTE_TO_LINK: i18n.PICK_NOTE_TO_LINK;
|
|
440
444
|
UNTITLED: i18n.UNTITLED;
|
|
441
445
|
NO_SELECTED_NOTE: i18n.NO_SELECTED_NOTE;
|
|
446
|
+
GPG_EMAIL_REQUIRED: i18n.GPG_EMAIL_REQUIRED;
|
|
447
|
+
GPG_EMAIL_INVALID: i18n.GPG_EMAIL_INVALID;
|
|
442
448
|
};
|
|
443
449
|
export type I18N = i18n | DefaultCommands;
|
package/constants/i18n-keys.js
CHANGED
|
@@ -38,7 +38,7 @@ export var i18n;
|
|
|
38
38
|
i18n["GPG_PRIVATE_KEY"] = "GPG private key";
|
|
39
39
|
i18n["ENCRYPT_EXISTING_NOTES"] = "encrypt existing notes";
|
|
40
40
|
i18n["ENCRYPTION_KEYS_GEN_WARNING"] = "be careful, the old encryption keys will be lost. Third-party clients will need to update encryption keys.";
|
|
41
|
-
i18n["
|
|
41
|
+
i18n["ENCRYPTED_NOTES_KEY_CHANGE_WARNING"] = "you have encrypted notes. Changing encryption keys will make them unreadable unless you re-encrypt them manually. Continue?";
|
|
42
42
|
i18n["SYNC_FILES"] = "sync files";
|
|
43
43
|
i18n["SYNC_FILES_DESCRIPTION"] = "synchronize all local files with the remote server";
|
|
44
44
|
i18n["GENERATE_GPG_KEYS"] = "generate new GPG keys";
|
|
@@ -174,6 +174,9 @@ export var i18n;
|
|
|
174
174
|
i18n["PICK_NOTE_TO_LINK"] = "pick note to link";
|
|
175
175
|
i18n["UNTITLED"] = "untitled";
|
|
176
176
|
i18n["NO_SELECTED_NOTE"] = "no selected note";
|
|
177
|
+
// GPG
|
|
178
|
+
i18n["GPG_EMAIL_REQUIRED"] = "gpg email required";
|
|
179
|
+
i18n["GPG_EMAIL_INVALID"] = "gpg email invalid";
|
|
177
180
|
})(i18n || (i18n = {}));
|
|
178
181
|
export const I18N = {
|
|
179
182
|
...i18n,
|
|
@@ -21,6 +21,16 @@ export declare const encryptViaKeys: <T extends WithEncryptionContent<OrgNoteGpg
|
|
|
21
21
|
export declare const encryptViaPassword: <T extends WithEncryptionContent<OrgNotePasswordEncryption>>(args_0: T) => Promise<T["format"] extends "binary" ? Uint8Array<ArrayBufferLike> : string>;
|
|
22
22
|
export declare const decryptViaPassword: <T extends Omit<WithDecryptionContent<OrgNotePasswordEncryption>, "type">>(args_0: T) => Promise<T["format"] extends "binary" ? Uint8Array<ArrayBufferLike> : string>;
|
|
23
23
|
export declare const decryptViaKeys: <T extends Omit<WithDecryptionContent<OrgNoteGpgEncryption>, "type">>(args_0: T) => Promise<T["format"] extends "binary" ? Uint8Array<ArrayBufferLike> : string>;
|
|
24
|
+
export interface GenerateGpgKeysParams {
|
|
25
|
+
username: string;
|
|
26
|
+
email: string;
|
|
27
|
+
passphrase?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface GeneratedGpgKeys {
|
|
30
|
+
privateKey: string;
|
|
31
|
+
publicKey: string;
|
|
32
|
+
}
|
|
33
|
+
export declare const generateGpgKeys: (params: GenerateGpgKeysParams) => Promise<GeneratedGpgKeys>;
|
|
24
34
|
export declare const encrypt: <T extends WithEncryptionContent<OrgNoteEncryption>>(encryptionParams: T) => Promise<T["format"] extends "binary" ? Uint8Array : string>;
|
|
25
35
|
export declare const decrypt: <T extends WithDecryptionContent<OrgNoteEncryption>>(decryptionParams: T) => Promise<T["format"] extends "binary" ? Uint8Array : string>;
|
|
26
36
|
export declare function _encryptViaKeys<T extends WithEncryptionContent<OrgNoteGpgEncryption>>({ content, publicKey: armoredPublicKey, privateKey: armoredPrivateKey, privateKeyPassphrase, format, }: T): Promise<T['format'] extends 'binary' ? Uint8Array : string>;
|
package/encryption/encryption.js
CHANGED
|
@@ -1,49 +1,63 @@
|
|
|
1
|
-
import { createMessage, decrypt as _decrypt, decryptKey, encrypt as _encrypt, readKey, readMessage, readPrivateKey, } from 'openpgp';
|
|
1
|
+
import { createMessage, decrypt as _decrypt, decryptKey, encrypt as _encrypt, generateKey, readKey, readMessage, readPrivateKey, } from 'openpgp';
|
|
2
2
|
import { EncryptionType, } from "../models/encryption.js";
|
|
3
3
|
import { armor as _armor, unarmor as _unarmor, enums } from 'openpgp';
|
|
4
4
|
export class IncorrectOrMissingPrivateKeyPasswordError extends Error {
|
|
5
5
|
constructor(message) {
|
|
6
|
-
super(message);
|
|
6
|
+
super(message ?? 'Private key passphrase is missing or incorrect. Please check your encryption settings.');
|
|
7
7
|
this.name = 'IncorrectOrMissingPrivateKeyPasswordError';
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
10
|
export class ImpossibleToDecryptWithProvidedKeysError extends Error {
|
|
11
11
|
constructor(message) {
|
|
12
|
-
super(message);
|
|
12
|
+
super(message ?? 'Decryption failed. The provided keys cannot decrypt this file.');
|
|
13
13
|
this.name = 'ImpossibleToDecryptWithProvidedKeysError';
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
export class IncorrectEncryptionPasswordError extends Error {
|
|
17
17
|
constructor(message) {
|
|
18
|
-
super(message);
|
|
18
|
+
super(message ?? 'Incorrect encryption password.');
|
|
19
19
|
this.name = 'IncorrectEncryptionPasswordError';
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
export class NoKeysProvidedError extends Error {
|
|
23
23
|
constructor(message) {
|
|
24
|
-
super(message);
|
|
24
|
+
super(message ?? 'No encryption keys provided. Please configure keys in Settings → Encryption.');
|
|
25
25
|
this.name = 'NoKeysProvidedError';
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
export class NoPasswordProvidedError extends Error {
|
|
29
29
|
constructor(message) {
|
|
30
|
-
super(message);
|
|
30
|
+
super(message ?? 'No encryption password provided. Please configure password in Settings → Encryption.');
|
|
31
31
|
this.name = 'NoPasswordProvidedError';
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const
|
|
42
|
-
const
|
|
34
|
+
const PRIVATE_KEY_NOT_DECRYPTED_PATTERNS = [
|
|
35
|
+
'Signing key is not decrypted',
|
|
36
|
+
'Incorrect key passphrase',
|
|
37
|
+
'Misformed armored text',
|
|
38
|
+
'Decryption key is not decrypted',
|
|
39
|
+
'Armored text not of type private key',
|
|
40
|
+
];
|
|
41
|
+
const DECRYPTION_FAILED_PATTERN = 'Session key decryption failed';
|
|
42
|
+
const INCORRECT_PASSWORD_PATTERN = 'Modification detected';
|
|
43
|
+
const NO_SYMMETRIC_KEY_PATTERN = 'No symmetrically encrypted session key packet found';
|
|
44
|
+
const NO_PUBLIC_KEY_PATTERN = 'No public key encrypted session key packet found';
|
|
43
45
|
export const encryptViaKeys = withCustomErrors(_encryptViaKeys);
|
|
44
46
|
export const encryptViaPassword = withCustomErrors(_encryptViaPassword);
|
|
45
47
|
export const decryptViaPassword = withCustomErrors(_decryptViaPassword);
|
|
46
48
|
export const decryptViaKeys = withCustomErrors(_decryptViaKeys);
|
|
49
|
+
export const generateGpgKeys = async (params) => {
|
|
50
|
+
const { privateKey, publicKey } = await generateKey({
|
|
51
|
+
type: 'curve25519',
|
|
52
|
+
userIDs: [{ name: params.username, email: params.email }],
|
|
53
|
+
passphrase: params.passphrase,
|
|
54
|
+
format: 'armored',
|
|
55
|
+
});
|
|
56
|
+
return {
|
|
57
|
+
privateKey,
|
|
58
|
+
publicKey,
|
|
59
|
+
};
|
|
60
|
+
};
|
|
47
61
|
export const encrypt = async (encryptionParams) => {
|
|
48
62
|
if (!encryptionParams.type ||
|
|
49
63
|
encryptionParams.type === EncryptionType.Disabled) {
|
|
@@ -137,6 +151,7 @@ async function _decryptViaKeys({ privateKey: armoredPrivateKey, privateKeyPassph
|
|
|
137
151
|
});
|
|
138
152
|
return decryptedText;
|
|
139
153
|
}
|
|
154
|
+
const messageContains = (message, pattern) => message.includes(pattern);
|
|
140
155
|
function withCustomErrors(fn) {
|
|
141
156
|
return async (...args) => {
|
|
142
157
|
try {
|
|
@@ -146,25 +161,20 @@ function withCustomErrors(fn) {
|
|
|
146
161
|
if (!(e instanceof Error)) {
|
|
147
162
|
throw e;
|
|
148
163
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
corruptedPrivateKeyErrorMsg,
|
|
153
|
-
decryptionKeyIsNotDecryptedErrorMsg,
|
|
154
|
-
armoredTextNotTypePrivateKeyErrorMsg,
|
|
155
|
-
].includes(e.message)) {
|
|
156
|
-
throw new IncorrectOrMissingPrivateKeyPasswordError(e.message);
|
|
164
|
+
const msg = e.message;
|
|
165
|
+
if (PRIVATE_KEY_NOT_DECRYPTED_PATTERNS.some((p) => messageContains(msg, p))) {
|
|
166
|
+
throw new IncorrectOrMissingPrivateKeyPasswordError();
|
|
157
167
|
}
|
|
158
|
-
if (
|
|
159
|
-
throw new ImpossibleToDecryptWithProvidedKeysError(
|
|
168
|
+
if (messageContains(msg, DECRYPTION_FAILED_PATTERN)) {
|
|
169
|
+
throw new ImpossibleToDecryptWithProvidedKeysError();
|
|
160
170
|
}
|
|
161
|
-
if (
|
|
171
|
+
if (messageContains(msg, INCORRECT_PASSWORD_PATTERN)) {
|
|
162
172
|
throw new IncorrectEncryptionPasswordError();
|
|
163
173
|
}
|
|
164
|
-
if (
|
|
174
|
+
if (messageContains(msg, NO_SYMMETRIC_KEY_PATTERN)) {
|
|
165
175
|
throw new NoKeysProvidedError();
|
|
166
176
|
}
|
|
167
|
-
if (
|
|
177
|
+
if (messageContains(msg, NO_PUBLIC_KEY_PATTERN)) {
|
|
168
178
|
throw new NoPasswordProvidedError();
|
|
169
179
|
}
|
|
170
180
|
throw e;
|
|
@@ -59,6 +59,9 @@ export declare enum DefaultCommands {
|
|
|
59
59
|
RELOAD_FILES = "reload files",
|
|
60
60
|
ENCRYPT_NOTE = "encrypt note",
|
|
61
61
|
DECRYPT_NOTE = "decrypt note",
|
|
62
|
+
UPLOAD_PRIVATE_KEY = "upload private key",
|
|
63
|
+
UPLOAD_PUBLIC_KEY = "upload public key",
|
|
64
|
+
GENERATE_GPG_KEYS = "generate gpg keys",
|
|
62
65
|
MAXIMIZE_FILE_MANAGER = "maximize file manager",
|
|
63
66
|
CREATE_FOLDER = "create folder",
|
|
64
67
|
CREATE_FILE = "create file",
|
|
@@ -72,6 +72,10 @@ export var DefaultCommands;
|
|
|
72
72
|
DefaultCommands["RELOAD_FILES"] = "reload files";
|
|
73
73
|
DefaultCommands["ENCRYPT_NOTE"] = "encrypt note";
|
|
74
74
|
DefaultCommands["DECRYPT_NOTE"] = "decrypt note";
|
|
75
|
+
// Encryption key management
|
|
76
|
+
DefaultCommands["UPLOAD_PRIVATE_KEY"] = "upload private key";
|
|
77
|
+
DefaultCommands["UPLOAD_PUBLIC_KEY"] = "upload public key";
|
|
78
|
+
DefaultCommands["GENERATE_GPG_KEYS"] = "generate gpg keys";
|
|
75
79
|
// File manager
|
|
76
80
|
DefaultCommands["MAXIMIZE_FILE_MANAGER"] = "maximize file manager";
|
|
77
81
|
DefaultCommands["CREATE_FOLDER"] = "create folder";
|
package/models/encryption.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { InferOutput } from 'valibot';
|
|
2
|
+
import { DefaultCommands } from './default-commands.js';
|
|
2
3
|
export declare const EncryptionType: {
|
|
3
4
|
readonly GpgKeys: "gpgKeys";
|
|
4
5
|
readonly GpgPassword: "gpgPassword";
|
|
@@ -17,16 +18,22 @@ declare const OrgNoteGpgEncryptionSchema: import("valibot").ObjectSchema<{
|
|
|
17
18
|
readonly privateKey: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MetadataAction<string, {
|
|
18
19
|
readonly textarea: true;
|
|
19
20
|
readonly upload: true;
|
|
21
|
+
readonly command: DefaultCommands.UPLOAD_PRIVATE_KEY;
|
|
20
22
|
}>]>;
|
|
21
23
|
readonly publicKey: import("valibot").SchemaWithPipe<readonly [import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>, import("valibot").MetadataAction<string, {
|
|
22
24
|
readonly textarea: true;
|
|
23
25
|
readonly upload: true;
|
|
26
|
+
readonly command: DefaultCommands.UPLOAD_PUBLIC_KEY;
|
|
27
|
+
}>]>;
|
|
28
|
+
readonly privateKeyPassphrase: import("valibot").SchemaWithPipe<readonly [import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>, import("valibot").MetadataAction<string, {
|
|
29
|
+
readonly password: true;
|
|
24
30
|
}>]>;
|
|
25
|
-
readonly privateKeyPassphrase: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
26
31
|
}, undefined>;
|
|
27
32
|
declare const OrgNotePasswordEncryptionSchema: import("valibot").ObjectSchema<{
|
|
28
33
|
readonly type: import("valibot").LiteralSchema<"gpgPassword", undefined>;
|
|
29
|
-
readonly password: import("valibot").StringSchema<undefined
|
|
34
|
+
readonly password: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MetadataAction<string, {
|
|
35
|
+
readonly password: true;
|
|
36
|
+
}>]>;
|
|
30
37
|
}, undefined>;
|
|
31
38
|
export declare const OrgNoteEncryptionSchema: import("valibot").IntersectSchema<[import("valibot").ObjectSchema<{
|
|
32
39
|
readonly encryptFilesByDefault: import("valibot").OptionalSchema<import("valibot").BooleanSchema<undefined>, undefined>;
|
|
@@ -35,15 +42,21 @@ export declare const OrgNoteEncryptionSchema: import("valibot").IntersectSchema<
|
|
|
35
42
|
readonly privateKey: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MetadataAction<string, {
|
|
36
43
|
readonly textarea: true;
|
|
37
44
|
readonly upload: true;
|
|
45
|
+
readonly command: DefaultCommands.UPLOAD_PRIVATE_KEY;
|
|
38
46
|
}>]>;
|
|
39
47
|
readonly publicKey: import("valibot").SchemaWithPipe<readonly [import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>, import("valibot").MetadataAction<string, {
|
|
40
48
|
readonly textarea: true;
|
|
41
49
|
readonly upload: true;
|
|
50
|
+
readonly command: DefaultCommands.UPLOAD_PUBLIC_KEY;
|
|
51
|
+
}>]>;
|
|
52
|
+
readonly privateKeyPassphrase: import("valibot").SchemaWithPipe<readonly [import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>, import("valibot").MetadataAction<string, {
|
|
53
|
+
readonly password: true;
|
|
42
54
|
}>]>;
|
|
43
|
-
readonly privateKeyPassphrase: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
44
55
|
}, undefined>, import("valibot").ObjectSchema<{
|
|
45
56
|
readonly type: import("valibot").LiteralSchema<"gpgPassword", undefined>;
|
|
46
|
-
readonly password: import("valibot").StringSchema<undefined
|
|
57
|
+
readonly password: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MetadataAction<string, {
|
|
58
|
+
readonly password: true;
|
|
59
|
+
}>]>;
|
|
47
60
|
}, undefined>, import("valibot").ObjectSchema<{
|
|
48
61
|
readonly type: import("valibot").LiteralSchema<"disabled", undefined>;
|
|
49
62
|
}, undefined>], undefined>, import("valibot").MetadataAction<{
|
package/models/encryption.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { boolean, metadata } from 'valibot';
|
|
2
2
|
import { object, string, union, optional, literal, intersect, pipe, } from 'valibot';
|
|
3
|
+
import { DefaultCommands } from './default-commands.js';
|
|
3
4
|
export const EncryptionType = {
|
|
4
5
|
GpgKeys: 'gpgKeys',
|
|
5
6
|
GpgPassword: 'gpgPassword',
|
|
@@ -7,13 +8,21 @@ export const EncryptionType = {
|
|
|
7
8
|
};
|
|
8
9
|
const OrgNoteGpgEncryptionSchema = object({
|
|
9
10
|
type: literal(EncryptionType.GpgKeys),
|
|
10
|
-
privateKey: pipe(string(), metadata({
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
privateKey: pipe(string(), metadata({
|
|
12
|
+
textarea: true,
|
|
13
|
+
upload: true,
|
|
14
|
+
command: DefaultCommands.UPLOAD_PRIVATE_KEY,
|
|
15
|
+
})),
|
|
16
|
+
publicKey: pipe(optional(string()), metadata({
|
|
17
|
+
textarea: true,
|
|
18
|
+
upload: true,
|
|
19
|
+
command: DefaultCommands.UPLOAD_PUBLIC_KEY,
|
|
20
|
+
})),
|
|
21
|
+
privateKeyPassphrase: pipe(optional(string()), metadata({ password: true })),
|
|
13
22
|
});
|
|
14
23
|
const OrgNotePasswordEncryptionSchema = object({
|
|
15
24
|
type: literal(EncryptionType.GpgPassword),
|
|
16
|
-
password: string(),
|
|
25
|
+
password: pipe(string(), metadata({ password: true })),
|
|
17
26
|
});
|
|
18
27
|
const OrgNoteDisabledEncryptionSchema = object({
|
|
19
28
|
type: literal(EncryptionType.Disabled),
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/models/index.d.ts
CHANGED
|
@@ -85,6 +85,7 @@ export * from './font-store.js';
|
|
|
85
85
|
export * from './file-search-store.js';
|
|
86
86
|
export * from './file-meta-store.js';
|
|
87
87
|
export * from './embedded-buffer-store.js';
|
|
88
|
+
export * from './file-content.js';
|
|
88
89
|
export * from './style-variant.js';
|
|
89
90
|
export * from './style-size.js';
|
|
90
91
|
export * from './repositories.js';
|
package/models/index.js
CHANGED
|
@@ -87,6 +87,7 @@ export * from "./font-store.js";
|
|
|
87
87
|
export * from "./file-search-store.js";
|
|
88
88
|
export * from "./file-meta-store.js";
|
|
89
89
|
export * from "./embedded-buffer-store.js";
|
|
90
|
+
export * from "./file-content.js";
|
|
90
91
|
// UI
|
|
91
92
|
export * from "./style-variant.js";
|
|
92
93
|
export * from "./style-size.js";
|
package/models/modal.d.ts
CHANGED
|
@@ -56,15 +56,21 @@ export declare const ORG_NOTE_CONFIG_SCHEMA: import("valibot").SchemaWithPipe<re
|
|
|
56
56
|
readonly privateKey: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MetadataAction<string, {
|
|
57
57
|
readonly textarea: true;
|
|
58
58
|
readonly upload: true;
|
|
59
|
+
readonly command: import("./default-commands").DefaultCommands.UPLOAD_PRIVATE_KEY;
|
|
59
60
|
}>]>;
|
|
60
61
|
readonly publicKey: import("valibot").SchemaWithPipe<readonly [import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>, import("valibot").MetadataAction<string, {
|
|
61
62
|
readonly textarea: true;
|
|
62
63
|
readonly upload: true;
|
|
64
|
+
readonly command: import("./default-commands").DefaultCommands.UPLOAD_PUBLIC_KEY;
|
|
65
|
+
}>]>;
|
|
66
|
+
readonly privateKeyPassphrase: import("valibot").SchemaWithPipe<readonly [import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>, import("valibot").MetadataAction<string, {
|
|
67
|
+
readonly password: true;
|
|
63
68
|
}>]>;
|
|
64
|
-
readonly privateKeyPassphrase: import("valibot").OptionalSchema<import("valibot").StringSchema<undefined>, undefined>;
|
|
65
69
|
}, undefined>, import("valibot").ObjectSchema<{
|
|
66
70
|
readonly type: import("valibot").LiteralSchema<"gpgPassword", undefined>;
|
|
67
|
-
readonly password: import("valibot").StringSchema<undefined
|
|
71
|
+
readonly password: import("valibot").SchemaWithPipe<readonly [import("valibot").StringSchema<undefined>, import("valibot").MetadataAction<string, {
|
|
72
|
+
readonly password: true;
|
|
73
|
+
}>]>;
|
|
68
74
|
}, undefined>, import("valibot").ObjectSchema<{
|
|
69
75
|
readonly type: import("valibot").LiteralSchema<"disabled", undefined>;
|
|
70
76
|
}, undefined>], undefined>, import("valibot").MetadataAction<{
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { expect, test } from 'vitest';
|
|
2
|
-
import { isGpgEncrypted } from "../is-gpg-encrypted.js";
|
|
2
|
+
import { isArmoredPgp, isGpgEncrypted } from "../is-gpg-encrypted.js";
|
|
3
3
|
test('Should return true if the content is gpg encrypted', () => {
|
|
4
4
|
const content = `-----BEGIN PGP MESSAGE-----
|
|
5
5
|
|
|
@@ -38,3 +38,29 @@ test('Should return false if the content is not gpg encrypted', () => {
|
|
|
38
38
|
const content = `Hello World!`;
|
|
39
39
|
expect(isGpgEncrypted(content)).toBe(false);
|
|
40
40
|
});
|
|
41
|
+
test('isArmoredPgp should return true for armored PGP string', () => {
|
|
42
|
+
const armored = `-----BEGIN PGP MESSAGE-----\n\nbase64data\n-----END PGP MESSAGE-----`;
|
|
43
|
+
expect(isArmoredPgp(armored)).toBe(true);
|
|
44
|
+
});
|
|
45
|
+
test('isArmoredPgp should return true for armored PGP public key', () => {
|
|
46
|
+
const armored = `-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nkeydata\n-----END PGP PUBLIC KEY BLOCK-----`;
|
|
47
|
+
expect(isArmoredPgp(armored)).toBe(true);
|
|
48
|
+
});
|
|
49
|
+
test('isArmoredPgp should return false for plain text string', () => {
|
|
50
|
+
expect(isArmoredPgp('Hello World!')).toBe(false);
|
|
51
|
+
});
|
|
52
|
+
test('isArmoredPgp should return false for empty string', () => {
|
|
53
|
+
expect(isArmoredPgp('')).toBe(false);
|
|
54
|
+
});
|
|
55
|
+
test('isArmoredPgp should return true for Uint8Array with armored PGP header', () => {
|
|
56
|
+
const armored = '-----BEGIN PGP MESSAGE-----\n\ndata';
|
|
57
|
+
const bytes = new TextEncoder().encode(armored);
|
|
58
|
+
expect(isArmoredPgp(bytes)).toBe(true);
|
|
59
|
+
});
|
|
60
|
+
test('isArmoredPgp should return false for Uint8Array with binary content', () => {
|
|
61
|
+
const bytes = new Uint8Array([0x99, 0x01, 0x0d, 0x04, 0x5e]);
|
|
62
|
+
expect(isArmoredPgp(bytes)).toBe(false);
|
|
63
|
+
});
|
|
64
|
+
test('isArmoredPgp should return false for empty Uint8Array', () => {
|
|
65
|
+
expect(isArmoredPgp(new Uint8Array(0))).toBe(false);
|
|
66
|
+
});
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
const PGP_ARMOR_HEADER = '-----BEGIN PGP';
|
|
2
|
+
export function isArmoredPgp(content) {
|
|
3
|
+
if (typeof content === 'string') {
|
|
4
|
+
return content.startsWith(PGP_ARMOR_HEADER);
|
|
5
|
+
}
|
|
6
|
+
const header = String.fromCharCode(...content.slice(0, PGP_ARMOR_HEADER.length));
|
|
7
|
+
return header === PGP_ARMOR_HEADER;
|
|
8
|
+
}
|
|
1
9
|
export function isGpgEncrypted(text) {
|
|
2
10
|
if (text instanceof Uint8Array) {
|
|
3
11
|
return true;
|