mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
"sync now" button
This commit is contained in:
parent
c28b7775a5
commit
d613200925
20
public/javascripts/sync.js
Normal file
20
public/javascripts/sync.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
function syncNow() {
|
||||||
|
$.ajax({
|
||||||
|
url: baseApiUrl + 'sync/now',
|
||||||
|
type: 'POST',
|
||||||
|
success: result => {
|
||||||
|
if (result.success) {
|
||||||
|
alert("Sync finished successfully");
|
||||||
|
|
||||||
|
for (const l of result.log)
|
||||||
|
{
|
||||||
|
console.log(l);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
alert("Sync failed");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: () => alert("Sync failed")
|
||||||
|
});
|
||||||
|
}
|
@ -5,6 +5,15 @@ const router = express.Router();
|
|||||||
const auth = require('../../services/auth');
|
const auth = require('../../services/auth');
|
||||||
const sync = require('../../services/sync');
|
const sync = require('../../services/sync');
|
||||||
|
|
||||||
|
router.post('/now', auth.checkApiAuth, async (req, res, next) => {
|
||||||
|
const log = await sync.sync();
|
||||||
|
|
||||||
|
res.send({
|
||||||
|
success: true,
|
||||||
|
log: log
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
router.get('/changed/:since', auth.checkApiAuth, async (req, res, next) => {
|
router.get('/changed/:since', auth.checkApiAuth, async (req, res, next) => {
|
||||||
const since = parseInt(req.params.since);
|
const since = parseInt(req.params.since);
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ const SYNC_SERVER = config['Sync']['syncServerHost'];
|
|||||||
|
|
||||||
let syncInProgress = false;
|
let syncInProgress = false;
|
||||||
|
|
||||||
async function pullSync(cookieJar) {
|
async function pullSync(cookieJar, syncLog) {
|
||||||
const lastSyncedPull = parseInt(await sql.getOption('last_synced_pull'));
|
const lastSyncedPull = parseInt(await sql.getOption('last_synced_pull'));
|
||||||
|
|
||||||
const resp = await rp({
|
const resp = await rp({
|
||||||
@ -28,7 +28,7 @@ async function pullSync(cookieJar) {
|
|||||||
try {
|
try {
|
||||||
await sql.beginTransaction();
|
await sql.beginTransaction();
|
||||||
|
|
||||||
await putChanged(resp);
|
await putChanged(resp, syncLog);
|
||||||
|
|
||||||
for (const noteId of resp.notes) {
|
for (const noteId of resp.notes) {
|
||||||
const note = await rp({
|
const note = await rp({
|
||||||
@ -41,7 +41,7 @@ async function pullSync(cookieJar) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
await putNote(note);
|
await putNote(note, syncLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
await sql.setOption('last_synced_pull', resp.syncTimestamp);
|
await sql.setOption('last_synced_pull', resp.syncTimestamp);
|
||||||
@ -55,24 +55,30 @@ async function pullSync(cookieJar) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function pushSync(cookieJar) {
|
async function pushSync(cookieJar, syncLog) {
|
||||||
const lastSyncedPush = parseInt(await sql.getOption('last_synced_push'));
|
const lastSyncedPush = parseInt(await sql.getOption('last_synced_push'));
|
||||||
const syncStarted = utils.nowTimestamp();
|
const syncStarted = utils.nowTimestamp();
|
||||||
|
|
||||||
const changed = await getChangedSince(lastSyncedPush);
|
const changed = await getChangedSince(lastSyncedPush);
|
||||||
|
|
||||||
await rp({
|
if (changed.tree.length > 0 || changed.audit_log.length > 0) {
|
||||||
method: 'PUT',
|
logSync("Sending " + changed.tree.length + " tree changes and " + changed.audit_log.length + " audit changes", syncLog);
|
||||||
uri: SYNC_SERVER + '/api/sync/changed',
|
|
||||||
headers: {
|
await rp({
|
||||||
auth: 'sync'
|
method: 'PUT',
|
||||||
},
|
uri: SYNC_SERVER + '/api/sync/changed',
|
||||||
body: changed,
|
headers: {
|
||||||
json: true,
|
auth: 'sync'
|
||||||
jar: cookieJar
|
},
|
||||||
});
|
body: changed,
|
||||||
|
json: true,
|
||||||
|
jar: cookieJar
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
for (const noteId of changed.notes) {
|
for (const noteId of changed.notes) {
|
||||||
|
logSync("Sending note " + noteId, syncLog);
|
||||||
|
|
||||||
const note = await getNoteSince(noteId);
|
const note = await getNoteSince(noteId);
|
||||||
|
|
||||||
await rp({
|
await rp({
|
||||||
@ -93,8 +99,10 @@ async function pushSync(cookieJar) {
|
|||||||
async function login() {
|
async function login() {
|
||||||
const timestamp = utils.nowTimestamp();
|
const timestamp = utils.nowTimestamp();
|
||||||
|
|
||||||
const hmac = crypto.createHmac('sha256', documentSecret);
|
const documentSecret = await sql.getOption('document_secret');
|
||||||
hmac.update(timestamp);
|
|
||||||
|
const hmac = crypto.createHmac('sha256', Buffer.from(documentSecret.toString(), 'ASCII'));
|
||||||
|
hmac.update(timestamp.toString());
|
||||||
const hash = hmac.digest('base64');
|
const hash = hmac.digest('base64');
|
||||||
|
|
||||||
const cookieJar = rp.jar();
|
const cookieJar = rp.jar();
|
||||||
@ -120,6 +128,7 @@ async function sync() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
syncInProgress = true;
|
syncInProgress = true;
|
||||||
|
const syncLog = [];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!await migration.isDbUpToDate()) {
|
if (!await migration.isDbUpToDate()) {
|
||||||
@ -128,16 +137,26 @@ async function sync() {
|
|||||||
|
|
||||||
const cookieJar = await login();
|
const cookieJar = await login();
|
||||||
|
|
||||||
await pushSync(cookieJar);
|
await pushSync(cookieJar, syncLog);
|
||||||
|
|
||||||
await pullSync(cookieJar);
|
await pullSync(cookieJar, syncLog);
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
log.error("sync failed: " + e.stack);
|
logSync("sync failed: " + e.stack, syncLog);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
syncInProgress = false;
|
syncInProgress = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return syncLog;
|
||||||
|
}
|
||||||
|
|
||||||
|
function logSync(message, syncLog) {
|
||||||
|
log.info(message);
|
||||||
|
|
||||||
|
if (syncLog !== null) {
|
||||||
|
syncLog.push(message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getChangedSince(since) {
|
async function getChangedSince(since) {
|
||||||
@ -158,27 +177,29 @@ async function getNoteSince(noteId, since) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function putChanged(changed) {
|
async function putChanged(changed, syncLog) {
|
||||||
for (const treeItem of changed.tree) {
|
for (const treeItem of changed.tree) {
|
||||||
delete treeItem['id'];
|
delete treeItem['id'];
|
||||||
|
|
||||||
await sql.insert("notes_tree", treeItem, true);
|
await sql.insert("notes_tree", treeItem, true);
|
||||||
|
|
||||||
log.info("Update/sync notes_tree " + treeItem.note_id);
|
logSync("Update/sync notes_tree " + treeItem.note_id, syncLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const audit of changed.audit_log) {
|
for (const audit of changed.audit_log) {
|
||||||
await sql.insert("audit_log", audit, true);
|
await sql.insert("audit_log", audit, true);
|
||||||
|
|
||||||
log.info("Update/sync audit_log for noteId=" + audit.note_id);
|
logSync("Update/sync audit_log for noteId=" + audit.note_id, syncLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changed.tree.length > 0 || changed.audit_log.length > 0) {
|
if (changed.tree.length > 0 || changed.audit_log.length > 0) {
|
||||||
|
logSync("Added final audit", syncLog);
|
||||||
|
|
||||||
await sql.addAudit(audit_category.SYNC);
|
await sql.addAudit(audit_category.SYNC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function putNote(note) {
|
async function putNote(note, syncLog) {
|
||||||
const origNote = await sql.getSingleResult();
|
const origNote = await sql.getSingleResult();
|
||||||
|
|
||||||
if (origNote !== null && origNote.date_modified >= note.detail.date_modified) {
|
if (origNote !== null && origNote.date_modified >= note.detail.date_modified) {
|
||||||
@ -203,7 +224,7 @@ async function putNote(note) {
|
|||||||
|
|
||||||
await sql.addAudit(audit_category.SYNC);
|
await sql.addAudit(audit_category.SYNC);
|
||||||
|
|
||||||
log.info("Update/sync note " + note.detail.note_id);
|
logSync("Update/sync note " + note.detail.note_id, syncLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SYNC_SERVER) {
|
if (SYNC_SERVER) {
|
||||||
@ -219,6 +240,7 @@ else {
|
|||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
sync,
|
||||||
getChangedSince,
|
getChangedSince,
|
||||||
getNoteSince,
|
getNoteSince,
|
||||||
putChanged,
|
putChanged,
|
||||||
|
@ -19,7 +19,7 @@ function randomString(length) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function randomSecureToken(bytes = 32) {
|
function randomSecureToken(bytes = 32) {
|
||||||
crypto.randomBytes(bytes).toString('base64');
|
return crypto.randomBytes(bytes).toString('base64');
|
||||||
}
|
}
|
||||||
|
|
||||||
function nowTimestamp() {
|
function nowTimestamp() {
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
<span id="top-message"></span>
|
<span id="top-message"></span>
|
||||||
<span id="error-message"></span>
|
<span id="error-message"></span>
|
||||||
|
|
||||||
|
<button class="btn btn-xs" onclick="syncNow();">Sync now</button>
|
||||||
|
|
||||||
<button class="btn btn-xs" onclick="displaySettings();">Settings</button>
|
<button class="btn btn-xs" onclick="displaySettings();">Settings</button>
|
||||||
|
|
||||||
<form action="logout" method="POST" style="display: inline;">
|
<form action="logout" method="POST" style="display: inline;">
|
||||||
@ -274,6 +276,7 @@
|
|||||||
<script src="javascripts/note_history.js"></script>
|
<script src="javascripts/note_history.js"></script>
|
||||||
<script src="javascripts/recent_changes.js"></script>
|
<script src="javascripts/recent_changes.js"></script>
|
||||||
|
|
||||||
|
<script src="javascripts/sync.js"></script>
|
||||||
<script src="javascripts/utils.js"></script>
|
<script src="javascripts/utils.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
Loading…
x
Reference in New Issue
Block a user