mirror of
https://github.com/zadam/trilium.git
synced 2025-06-06 18:08:33 +02:00
converted image and maintainance routes
This commit is contained in:
parent
e36a81e189
commit
aa57a64c61
@ -1,15 +1,11 @@
|
||||
"use strict";
|
||||
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const anonymization = require('../../services/anonymization');
|
||||
const auth = require('../../services/auth');
|
||||
const wrap = require('express-promise-wrap').wrap;
|
||||
|
||||
router.post('/anonymize', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
async function anonymize() {
|
||||
await anonymization.anonymize();
|
||||
}
|
||||
|
||||
res.send({});
|
||||
}));
|
||||
|
||||
module.exports = router;
|
||||
module.exports = {
|
||||
anonymize
|
||||
};
|
@ -1,83 +1,73 @@
|
||||
"use strict";
|
||||
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const sql = require('../../services/sql');
|
||||
const utils = require('../../services/utils');
|
||||
const sync_table = require('../../services/sync_table');
|
||||
const auth = require('../../services/auth');
|
||||
const log = require('../../services/log');
|
||||
const wrap = require('express-promise-wrap').wrap;
|
||||
|
||||
router.post('/cleanup-soft-deleted-items', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
await sql.doInTransaction(async () => {
|
||||
const noteIdsToDelete = await sql.getColumn("SELECT noteId FROM notes WHERE isDeleted = 1");
|
||||
const noteIdsSql = noteIdsToDelete
|
||||
.map(noteId => "'" + utils.sanitizeSql(noteId) + "'")
|
||||
.join(', ');
|
||||
async function cleanupSoftDeletedItems() {
|
||||
const noteIdsToDelete = await sql.getColumn("SELECT noteId FROM notes WHERE isDeleted = 1");
|
||||
const noteIdsSql = noteIdsToDelete
|
||||
.map(noteId => "'" + utils.sanitizeSql(noteId) + "'")
|
||||
.join(', ');
|
||||
|
||||
await sql.execute(`DELETE FROM event_log WHERE noteId IN (${noteIdsSql})`);
|
||||
await sql.execute(`DELETE FROM event_log WHERE noteId IN (${noteIdsSql})`);
|
||||
|
||||
await sql.execute(`DELETE FROM note_revisions WHERE noteId IN (${noteIdsSql})`);
|
||||
await sql.execute(`DELETE FROM note_revisions WHERE noteId IN (${noteIdsSql})`);
|
||||
|
||||
await sql.execute(`DELETE FROM note_images WHERE noteId IN (${noteIdsSql})`);
|
||||
await sql.execute(`DELETE FROM note_images WHERE noteId IN (${noteIdsSql})`);
|
||||
|
||||
await sql.execute(`DELETE FROM labels WHERE noteId IN (${noteIdsSql})`);
|
||||
await sql.execute(`DELETE FROM labels WHERE noteId IN (${noteIdsSql})`);
|
||||
|
||||
await sql.execute("DELETE FROM branches WHERE isDeleted = 1");
|
||||
await sql.execute("DELETE FROM branches WHERE isDeleted = 1");
|
||||
|
||||
await sql.execute("DELETE FROM note_images WHERE isDeleted = 1");
|
||||
await sql.execute("DELETE FROM note_images WHERE isDeleted = 1");
|
||||
|
||||
await sql.execute("DELETE FROM images WHERE isDeleted = 1");
|
||||
await sql.execute("DELETE FROM images WHERE isDeleted = 1");
|
||||
|
||||
await sql.execute("DELETE FROM notes WHERE isDeleted = 1");
|
||||
await sql.execute("DELETE FROM notes WHERE isDeleted = 1");
|
||||
|
||||
await sql.execute("DELETE FROM recent_notes");
|
||||
await sql.execute("DELETE FROM recent_notes");
|
||||
|
||||
await sync_table.cleanupSyncRowsForMissingEntities("notes", "noteId");
|
||||
await sync_table.cleanupSyncRowsForMissingEntities("branches", "branchId");
|
||||
await sync_table.cleanupSyncRowsForMissingEntities("note_revisions", "noteRevisionId");
|
||||
await sync_table.cleanupSyncRowsForMissingEntities("recent_notes", "branchId");
|
||||
await sync_table.cleanupSyncRowsForMissingEntities("notes", "noteId");
|
||||
await sync_table.cleanupSyncRowsForMissingEntities("branches", "branchId");
|
||||
await sync_table.cleanupSyncRowsForMissingEntities("note_revisions", "noteRevisionId");
|
||||
await sync_table.cleanupSyncRowsForMissingEntities("recent_notes", "branchId");
|
||||
|
||||
log.info("Following notes has been completely cleaned from database: " + noteIdsSql);
|
||||
});
|
||||
log.info("Following notes has been completely cleaned from database: " + noteIdsSql);
|
||||
}
|
||||
|
||||
res.send({});
|
||||
}));
|
||||
|
||||
router.post('/cleanup-unused-images', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
async function cleanupUnusedImages() {
|
||||
const sourceId = req.headers.source_id;
|
||||
|
||||
await sql.doInTransaction(async () => {
|
||||
const unusedImageIds = await sql.getColumn(`
|
||||
SELECT images.imageId
|
||||
FROM images
|
||||
LEFT JOIN note_images ON note_images.imageId = images.imageId AND note_images.isDeleted = 0
|
||||
WHERE
|
||||
images.isDeleted = 0
|
||||
AND note_images.noteImageId IS NULL`);
|
||||
const unusedImageIds = await sql.getColumn(`
|
||||
SELECT images.imageId
|
||||
FROM images
|
||||
LEFT JOIN note_images ON note_images.imageId = images.imageId AND note_images.isDeleted = 0
|
||||
WHERE
|
||||
images.isDeleted = 0
|
||||
AND note_images.noteImageId IS NULL`);
|
||||
|
||||
const now = utils.nowDate();
|
||||
const now = utils.nowDate();
|
||||
|
||||
for (const imageId of unusedImageIds) {
|
||||
log.info(`Deleting unused image: ${imageId}`);
|
||||
for (const imageId of unusedImageIds) {
|
||||
log.info(`Deleting unused image: ${imageId}`);
|
||||
|
||||
await sql.execute("UPDATE images SET isDeleted = 1, data = null, dateModified = ? WHERE imageId = ?",
|
||||
[now, imageId]);
|
||||
await sql.execute("UPDATE images SET isDeleted = 1, data = null, dateModified = ? WHERE imageId = ?",
|
||||
[now, imageId]);
|
||||
|
||||
await sync_table.addImageSync(imageId, sourceId);
|
||||
}
|
||||
});
|
||||
await sync_table.addImageSync(imageId, sourceId);
|
||||
}
|
||||
}
|
||||
|
||||
res.send({});
|
||||
}));
|
||||
|
||||
router.post('/vacuum-database', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
async function vacuumDatabase() {
|
||||
await sql.execute("VACUUM");
|
||||
|
||||
log.info("Database has been vacuumed.");
|
||||
}
|
||||
|
||||
res.send({});
|
||||
}));
|
||||
|
||||
module.exports = router;
|
||||
module.exports = {
|
||||
cleanupSoftDeletedItems,
|
||||
cleanupUnusedImages,
|
||||
vacuumDatabase
|
||||
};
|
@ -10,7 +10,7 @@ const wrap = require('express-promise-wrap').wrap;
|
||||
const RESOURCE_DIR = require('../../services/resource_dir').RESOURCE_DIR;
|
||||
const fs = require('fs');
|
||||
|
||||
router.get('/:imageId/:filename', auth.checkApiAuthOrElectron, wrap(async (req, res, next) => {
|
||||
async function returnImage(req, res) {
|
||||
const image = await sql.getRow("SELECT * FROM images WHERE imageId = ?", [req.params.imageId]);
|
||||
|
||||
if (!image) {
|
||||
@ -24,9 +24,9 @@ router.get('/:imageId/:filename', auth.checkApiAuthOrElectron, wrap(async (req,
|
||||
res.set('Content-Type', 'image/' + image.format);
|
||||
|
||||
res.send(image.data);
|
||||
}));
|
||||
}
|
||||
|
||||
router.post('', auth.checkApiAuthOrElectron, multer.single('upload'), wrap(async (req, res, next) => {
|
||||
async function uploadImage(req, res) {
|
||||
const sourceId = req.headers.source_id;
|
||||
const noteId = req.query.noteId;
|
||||
const file = req.file;
|
||||
@ -47,6 +47,9 @@ router.post('', auth.checkApiAuthOrElectron, multer.single('upload'), wrap(async
|
||||
uploaded: true,
|
||||
url: `/api/images/${imageId}/${fileName}`
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
module.exports = router;
|
||||
module.exports = {
|
||||
returnImage,
|
||||
uploadImage
|
||||
};
|
@ -1,33 +1,27 @@
|
||||
"use strict";
|
||||
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const auth = require('../../services/auth');
|
||||
const options = require('../../services/options');
|
||||
const sql = require('../../services/sql');
|
||||
const utils = require('../../services/utils');
|
||||
const my_scrypt = require('../../services/my_scrypt');
|
||||
const password_encryption = require('../../services/password_encryption');
|
||||
const wrap = require('express-promise-wrap').wrap;
|
||||
|
||||
router.post('', auth.checkAppNotInitialized, wrap(async (req, res, next) => {
|
||||
async function setup(req) {
|
||||
const { username, password } = req.body;
|
||||
|
||||
await sql.doInTransaction(async () => {
|
||||
await options.setOption('username', username);
|
||||
await options.setOption('username', username);
|
||||
|
||||
await options.setOption('password_verification_salt', utils.randomSecureToken(32));
|
||||
await options.setOption('password_derived_key_salt', utils.randomSecureToken(32));
|
||||
await options.setOption('password_verification_salt', utils.randomSecureToken(32));
|
||||
await options.setOption('password_derived_key_salt', utils.randomSecureToken(32));
|
||||
|
||||
const passwordVerificationKey = utils.toBase64(await my_scrypt.getVerificationHash(password));
|
||||
await options.setOption('password_verification_hash', passwordVerificationKey);
|
||||
const passwordVerificationKey = utils.toBase64(await my_scrypt.getVerificationHash(password));
|
||||
await options.setOption('password_verification_hash', passwordVerificationKey);
|
||||
|
||||
await password_encryption.setDataKey(password, utils.randomSecureToken(16));
|
||||
});
|
||||
await password_encryption.setDataKey(password, utils.randomSecureToken(16));
|
||||
|
||||
sql.setDbReadyAsResolved();
|
||||
}
|
||||
|
||||
res.send({});
|
||||
}));
|
||||
|
||||
module.exports = router;
|
||||
module.exports = {
|
||||
setup
|
||||
};
|
@ -1,26 +1,24 @@
|
||||
"use strict";
|
||||
|
||||
const express = require('express');
|
||||
const router = express.Router();
|
||||
const auth = require('../../services/auth');
|
||||
const sql = require('../../services/sql');
|
||||
const wrap = require('express-promise-wrap').wrap;
|
||||
|
||||
router.post('/execute', auth.checkApiAuth, wrap(async (req, res, next) => {
|
||||
async function execute(req) {
|
||||
const query = req.body.query;
|
||||
|
||||
try {
|
||||
res.send({
|
||||
return {
|
||||
success: true,
|
||||
rows: await sql.getRows(query)
|
||||
});
|
||||
};
|
||||
}
|
||||
catch (e) {
|
||||
res.send({
|
||||
return {
|
||||
success: false,
|
||||
error: e.message
|
||||
});
|
||||
};
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
module.exports = router;
|
||||
module.exports = {
|
||||
execute
|
||||
};
|
@ -40,44 +40,35 @@ const auth = require('../services/auth');
|
||||
const cls = require('../services/cls');
|
||||
const sql = require('../services/sql');
|
||||
|
||||
function apiRoute(method, path, routeHandler) {
|
||||
route({
|
||||
method,
|
||||
path,
|
||||
middleware: [auth.checkApiAuth],
|
||||
routeHandler,
|
||||
resultHandler: (res, result) => {
|
||||
// if it's an array and first element is integer then we consider this to be [statusCode, response] format
|
||||
if (Array.isArray(result) && result.length > 0 && Number.isInteger(result[0])) {
|
||||
const [statusCode, response] = result;
|
||||
function apiResultHandler(res, result) {
|
||||
// if it's an array and first element is integer then we consider this to be [statusCode, response] format
|
||||
if (Array.isArray(result) && result.length > 0 && Number.isInteger(result[0])) {
|
||||
const [statusCode, response] = result;
|
||||
|
||||
res.status(statusCode).send(response);
|
||||
res.status(statusCode).send(response);
|
||||
|
||||
if (statusCode !== 200) {
|
||||
log.info(`${method} ${path} returned ${statusCode} with response ${JSON.stringify(response)}`);
|
||||
}
|
||||
}
|
||||
else if (result === undefined) {
|
||||
res.status(200).send();
|
||||
}
|
||||
else {
|
||||
res.status(200).send(result);
|
||||
}
|
||||
if (statusCode !== 200) {
|
||||
log.info(`${method} ${path} returned ${statusCode} with response ${JSON.stringify(response)}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (result === undefined) {
|
||||
res.status(200).send();
|
||||
}
|
||||
else {
|
||||
res.status(200).send(result);
|
||||
}
|
||||
}
|
||||
|
||||
function apiRoute(method, path, routeHandler) {
|
||||
route(method, path, [auth.checkApiAuth], routeHandler, apiResultHandler);
|
||||
}
|
||||
|
||||
// API routes requiring HTTP protocol. This means we ignore route return value and make an electron auth exception
|
||||
function httpApiRoute(method, path, routeHandler) {
|
||||
route({
|
||||
method,
|
||||
path,
|
||||
middleware: [auth.checkApiAuth, multer.single('upload')],
|
||||
routeHandler
|
||||
})
|
||||
route(method, path, [auth.checkApiAuth, multer.single('upload')], routeHandler);
|
||||
}
|
||||
|
||||
function route({ method, path, middleware, routeHandler, resultHandler }) {
|
||||
function route(method, path, middleware, routeHandler, resultHandler) {
|
||||
router[method](path, ...middleware, async (req, res, next) => {
|
||||
try {
|
||||
const result = await cls.init(async () => {
|
||||
@ -176,14 +167,19 @@ function register(app) {
|
||||
apiRoute(GET, '/api/app-info', appInfoRoute.getAppInfo);
|
||||
|
||||
httpApiRoute(GET, '/api/export/:noteId', exportRoute.exportNote);
|
||||
|
||||
httpApiRoute(POST, '/api/import/:parentNoteId', importRoute.importTar);
|
||||
|
||||
app.use('/api/setup', setupApiRoute);
|
||||
app.use('/api/sql', sqlRoute);
|
||||
app.use('/api/anonymization', anonymizationRoute);
|
||||
app.use('/api/cleanup', cleanupRoute);
|
||||
app.use('/api/images', imageRoute);
|
||||
route(POST, '/api/setup', [auth.checkAppNotInitialized], setupApiRoute.setup, apiResultHandler);
|
||||
|
||||
apiRoute(POST, '/api/sql/execute', sqlRoute.execute);
|
||||
apiRoute(POST, '/api/anonymization/anonymize', anonymizationRoute.anonymize);
|
||||
|
||||
apiRoute(POST, '/api/cleanup/cleanup-soft-deleted-items', cleanupRoute.cleanupSoftDeletedItems);
|
||||
apiRoute(POST, '/api/cleanup/cleanup-unused-images', cleanupRoute.cleanupUnusedImages);
|
||||
apiRoute(POST, '/api/cleanup/vacuum-database', cleanupRoute.vacuumDatabase);
|
||||
|
||||
httpApiRoute(GET, '/api/images/:imageId/:filename', imageRoute.returnImage);
|
||||
httpApiRoute(POST, '/api/images', imageRoute.uploadImage);
|
||||
app.use('/api/script', scriptRoute);
|
||||
app.use('/api/sender', senderRoute);
|
||||
app.use('/api/files', filesRoute);
|
||||
|
Loading…
x
Reference in New Issue
Block a user