feat: Initial clean release of CHM
一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
这个提交包含在:
@@ -0,0 +1,49 @@
|
||||
import { NoteEntity } from '../database/types';
|
||||
import NoteLockService from './NoteLockService';
|
||||
import type { DecryptedNoteLockKey } from './NoteLockKey';
|
||||
|
||||
// The marker a gated load stamps on a note. Not a database column, so it cannot live on the
|
||||
// generated NoteEntity type.
|
||||
export type NoteLockNoteEntity = NoteEntity & { isDecrypted?: boolean };
|
||||
|
||||
export default class NoteLockNote {
|
||||
|
||||
public static isLocked(note: NoteEntity): boolean {
|
||||
if (!note) return false;
|
||||
return !!note.is_locked;
|
||||
}
|
||||
|
||||
public static isLocking(note: NoteEntity, oldNote: NoteEntity): boolean {
|
||||
if (!oldNote) return false;
|
||||
return this.isLocked(note) && !oldNote.is_locked;
|
||||
}
|
||||
|
||||
public static async decryptBody(note: NoteEntity, key: DecryptedNoteLockKey = null): Promise<NoteLockNoteEntity> {
|
||||
if (!note) throw new Error('Gated note lock load is missing note');
|
||||
if (note.is_locked === undefined) throw new Error('Gated note lock load is missing lock state');
|
||||
const isLocked = this.isLocked(note);
|
||||
// The marker means the note was loaded with the gate, locked or not.
|
||||
const result = { ...note, isDecrypted: true };
|
||||
if (isLocked) {
|
||||
// A missing body here means the gated load did not request enough fields, so pass an empty string and let decryption fail explicitly.
|
||||
result.body = await NoteLockService.withDecryptedKey(scoped => scoped.decryptString(note.body ?? ''), key);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static async prepareForSave(note: NoteLockNoteEntity, linkedItemIds: (body: string)=> string[], serializeResourceIds: (resourceIds: string[])=> string, isNew: boolean, useNoteLock: boolean, key: DecryptedNoteLockKey = null) {
|
||||
if (!note) throw new Error('Gated note lock save is missing note');
|
||||
if (!('body' in note)) throw new Error('Gated note lock save is missing body');
|
||||
const isLocked = this.isLocked(note);
|
||||
// The marker proves the data came from a gated load, so a cipher body is never encrypted
|
||||
// a second time and a missed gated load fails during development, locked note or not.
|
||||
if (useNoteLock && !isNew && !note.isDecrypted) throw new Error('Gated note lock save is missing decrypted state');
|
||||
if (!isLocked) note.extracted_resource_ids = '';
|
||||
|
||||
const plainTextBody = note.body ?? '';
|
||||
if (isLocked) {
|
||||
note.extracted_resource_ids = serializeResourceIds(linkedItemIds(plainTextBody));
|
||||
note.body = await NoteLockService.withDecryptedKey(scoped => scoped.encryptString(plainTextBody), key);
|
||||
}
|
||||
}
|
||||
}
|
||||
在新工单中引用
屏蔽一个用户