diff --git a/electron.js b/electron.js index 86d93bd49..64a13493f 100644 --- a/electron.js +++ b/electron.js @@ -73,10 +73,10 @@ app.on('ready', () => { mainWindow = createMainWindow(); const result = globalShortcut.register('CommandOrControl+Alt+P', async () => { - const date_notes = require('./src/services/date_notes'); - const utils = require('./src/services/utils'); + const dateNoteService = require('./src/services/date_notes'); + const dateUtils = require('./src/services/date_utils'); - const parentNoteId = await date_notes.getDateNoteId(utils.nowDate()); + const parentNoteId = await dateNoteService.getDateNoteId(dateUtils.nowDate()); // window may be hidden / not in focus mainWindow.focus(); diff --git a/src/entities/api_token.js b/src/entities/api_token.js index 9d50a4479..ecf2a9838 100644 --- a/src/entities/api_token.js +++ b/src/entities/api_token.js @@ -1,7 +1,7 @@ "use strict"; const Entity = require('./entity'); -const utils = require('../services/utils'); +const dateUtils = require('../services/date_utils'); class ApiToken extends Entity { static get tableName() { return "api_tokens"; } @@ -15,7 +15,7 @@ class ApiToken extends Entity { } if (!this.dateCreated) { - this.dateCreated = utils.nowDate(); + this.dateCreated = dateUtils.nowDate(); } } } diff --git a/src/entities/branch.js b/src/entities/branch.js index 11fa2c1ec..b17b68c79 100644 --- a/src/entities/branch.js +++ b/src/entities/branch.js @@ -1,7 +1,7 @@ "use strict"; const Entity = require('./entity'); -const utils = require('../services/utils'); +const dateUtils = require('../services/date_utils'); const repository = require('../services/repository'); class Branch extends Entity { @@ -19,7 +19,7 @@ class Branch extends Entity { this.isDeleted = false; } - this.dateModified = utils.nowDate() + this.dateModified = dateUtils.nowDate() } } diff --git a/src/entities/entity.js b/src/entities/entity.js index 40c1a9969..e3ef102b5 100644 --- a/src/entities/entity.js +++ b/src/entities/entity.js @@ -5,8 +5,6 @@ const repository = require('../services/repository'); class Entity { constructor(row = {}) { - utils.assertArguments(row); - for (const key in row) { this[key] = row[key]; } diff --git a/src/entities/image.js b/src/entities/image.js index 8bd995f94..437f6d859 100644 --- a/src/entities/image.js +++ b/src/entities/image.js @@ -1,7 +1,7 @@ "use strict"; const Entity = require('./entity'); -const utils = require('../services/utils'); +const dateUtils = require('../services/date_utils'); class Image extends Entity { static get tableName() { return "images"; } @@ -15,10 +15,10 @@ class Image extends Entity { } if (!this.dateCreated) { - this.dateCreated = utils.nowDate(); + this.dateCreated = dateUtils.nowDate(); } - this.dateModified = utils.nowDate(); + this.dateModified = dateUtils.nowDate(); } } diff --git a/src/entities/label.js b/src/entities/label.js index 3112e3709..59e4ad5ec 100644 --- a/src/entities/label.js +++ b/src/entities/label.js @@ -2,7 +2,7 @@ const Entity = require('./entity'); const repository = require('../services/repository'); -const utils = require('../services/utils'); +const dateUtils = require('../services/date_utils'); const sql = require('../services/sql'); class Label extends Entity { @@ -30,10 +30,10 @@ class Label extends Entity { } if (!this.dateCreated) { - this.dateCreated = utils.nowDate(); + this.dateCreated = dateUtils.nowDate(); } - this.dateModified = utils.nowDate(); + this.dateModified = dateUtils.nowDate(); } } diff --git a/src/entities/note.js b/src/entities/note.js index 3b4810d6a..c11833667 100644 --- a/src/entities/note.js +++ b/src/entities/note.js @@ -3,7 +3,7 @@ const Entity = require('./entity'); const protected_session = require('../services/protected_session'); const repository = require('../services/repository'); -const utils = require('../services/utils'); +const dateUtils = require('../services/date_utils'); class Note extends Entity { static get tableName() { return "notes"; } @@ -146,10 +146,10 @@ class Note extends Entity { } if (!this.dateCreated) { - this.dateCreated = utils.nowDate(); + this.dateCreated = dateUtils.nowDate(); } - this.dateModified = utils.nowDate(); + this.dateModified = dateUtils.nowDate(); } } diff --git a/src/entities/note_image.js b/src/entities/note_image.js index 8f1340773..8483f270c 100644 --- a/src/entities/note_image.js +++ b/src/entities/note_image.js @@ -2,7 +2,7 @@ const Entity = require('./entity'); const repository = require('../services/repository'); -const utils = require('../services/utils'); +const dateUtils = require('../services/date_utils'); class NoteImage extends Entity { static get tableName() { return "note_images"; } @@ -24,10 +24,10 @@ class NoteImage extends Entity { } if (!this.dateCreated) { - this.dateCreated = utils.nowDate(); + this.dateCreated = dateUtils.nowDate(); } - this.dateModified = utils.nowDate(); + this.dateModified = dateUtils.nowDate(); } } diff --git a/src/routes/api/cleanup.js b/src/routes/api/cleanup.js index 4304b28ed..d94f0c67a 100644 --- a/src/routes/api/cleanup.js +++ b/src/routes/api/cleanup.js @@ -50,8 +50,6 @@ async function cleanupUnusedImages() { images.isDeleted = 0 AND note_images.noteImageId IS NULL`); - const now = utils.nowDate(); - for (const imageId of unusedImageIds) { log.info(`Deleting unused image: ${imageId}`); diff --git a/src/routes/api/login.js b/src/routes/api/login.js index 39caa2c2e..e976be95f 100644 --- a/src/routes/api/login.js +++ b/src/routes/api/login.js @@ -2,6 +2,7 @@ const options = require('../../services/options'); const utils = require('../../services/utils'); +const dateUtils = require('../../services/date_utils'); const sourceIdService = require('../../services/source_id'); const passwordEncryptionService = require('../../services/password_encryption'); const protectedSessionService = require('../../services/protected_session'); @@ -10,7 +11,7 @@ const appInfo = require('../../services/app_info'); async function loginSync(req) { const timestampStr = req.body.timestamp; - const timestamp = utils.parseDateTime(timestampStr); + const timestamp = dateUtils.parseDateTime(timestampStr); const now = new Date(); diff --git a/src/routes/api/recent_notes.js b/src/routes/api/recent_notes.js index f6dccf8ae..38b6f1a20 100644 --- a/src/routes/api/recent_notes.js +++ b/src/routes/api/recent_notes.js @@ -1,7 +1,7 @@ "use strict"; const repository = require('../../services/repository'); -const utils = require('../../services/utils'); +const dateUtils = require('../../services/date_utils'); const optionService = require('../../services/options'); const RecentNote = require('../../entities/recent_note'); @@ -27,7 +27,7 @@ async function addRecentNote(req) { const recentNote = new RecentNote({ branchId: branchId, notePath: notePath, - dateAccessed: utils.nowDate(), + dateAccessed: dateUtils.nowDate(), isDeleted: 0 }); diff --git a/src/services/anonymization.js b/src/services/anonymization.js index 37f0dd80a..76a9abae4 100644 --- a/src/services/anonymization.js +++ b/src/services/anonymization.js @@ -1,7 +1,7 @@ "use strict"; const dataDir = require('./data_dir'); -const utils = require('./utils'); +const dateUtils = require('./date_utils'); const fs = require('fs-extra'); const sqlite = require('sqlite'); @@ -10,7 +10,7 @@ async function anonymize() { fs.mkdirSync(dataDir.ANONYMIZED_DB_DIR, 0o700); } - const anonymizedFile = dataDir.ANONYMIZED_DB_DIR + "/" + "backup-" + utils.getDateTimeForFile() + ".db"; + const anonymizedFile = dataDir.ANONYMIZED_DB_DIR + "/" + "backup-" + dateUtils.getDateTimeForFile() + ".db"; fs.copySync(dataDir.DOCUMENT_PATH, anonymizedFile); diff --git a/src/services/backup.js b/src/services/backup.js index e4db02214..840bfb481 100644 --- a/src/services/backup.js +++ b/src/services/backup.js @@ -1,6 +1,6 @@ "use strict"; -const utils = require('./utils'); +const dateUtils = require('./date_utils'); const optionService = require('./options'); const fs = require('fs-extra'); const dataDir = require('./data_dir'); @@ -11,7 +11,7 @@ const cls = require('./cls'); async function regularBackup() { const now = new Date(); - const lastBackupDate = utils.parseDateTime(await optionService.getOption('last_backup_date')); + const lastBackupDate = dateUtils.parseDateTime(await optionService.getOption('last_backup_date')); console.log(lastBackupDate); @@ -26,15 +26,13 @@ async function backupNow() { // we don't want to backup DB in the middle of sync with potentially inconsistent DB state await syncMutexService.doExclusively(async () => { - const now = utils.nowDate(); - - const backupFile = dataDir.BACKUP_DIR + "/" + "backup-" + utils.getDateTimeForFile() + ".db"; + const backupFile = dataDir.BACKUP_DIR + "/" + "backup-" + dateUtils.getDateTimeForFile() + ".db"; fs.copySync(dataDir.DOCUMENT_PATH, backupFile); log.info("Created backup at " + backupFile); - await optionService.setOption('last_backup_date', now); + await optionService.setOption('last_backup_date', dateUtils.nowDate()); }); } diff --git a/src/services/consistency_checks.js b/src/services/consistency_checks.js index 58aafd609..17fcc39d6 100644 --- a/src/services/consistency_checks.js +++ b/src/services/consistency_checks.js @@ -4,12 +4,9 @@ const sql = require('./sql'); const log = require('./log'); const messagingService = require('./messaging'); const syncMutexService = require('./sync_mutex'); -const utils = require('./utils'); const cls = require('./cls'); async function runCheck(query, errorText, errorList) { - utils.assertArguments(query, errorText, errorList); - const result = await sql.getColumn(query); if (result.length > 0) { diff --git a/src/services/date_notes.js b/src/services/date_notes.js index 8b04eddb1..65730cc81 100644 --- a/src/services/date_notes.js +++ b/src/services/date_notes.js @@ -3,7 +3,7 @@ const sql = require('./sql'); const noteService = require('./notes'); const labelService = require('./labels'); -const utils = require('./utils'); +const dateUtils = require('./date_utils'); const CALENDAR_ROOT_LABEL = 'calendar_root'; const YEAR_LABEL = 'year_note'; @@ -80,7 +80,7 @@ async function getMonthNoteId(dateTimeStr, rootNoteId) { monthNoteId = await getNoteStartingWith(yearNoteId, monthNumber); if (!monthNoteId) { - const dateObj = utils.parseDate(dateTimeStr); + const dateObj = dateUtils.parseDate(dateTimeStr); const noteTitle = monthNumber + " - " + MONTHS[dateObj.getMonth()]; @@ -109,7 +109,7 @@ async function getDateNoteId(dateTimeStr, rootNoteId = null) { dateNoteId = await getNoteStartingWith(monthNoteId, dayNumber); if (!dateNoteId) { - const dateObj = utils.parseDate(dateTimeStr); + const dateObj = dateUtils.parseDate(dateTimeStr); const noteTitle = dayNumber + " - " + DAYS[dateObj.getDay()]; diff --git a/src/services/date_utils.js b/src/services/date_utils.js new file mode 100644 index 000000000..2923351df --- /dev/null +++ b/src/services/date_utils.js @@ -0,0 +1,38 @@ +function nowDate() { + return dateStr(new Date()); +} + +function dateStr(date) { + return date.toISOString(); +} + +/** + * @param str - needs to be in the ISO 8601 format "YYYY-MM-DDTHH:MM:SS.sssZ" format as outputted by dateStr(). + * also is assumed to be GMT time (as indicated by the "Z" at the end), *not* local time + */ +function parseDateTime(str) { + try { + return new Date(Date.parse(str)); + } + catch (e) { + throw new Error("Can't parse date from " + str + ": " + e.stack); + } +} + +function parseDate(str) { + const datePart = str.substr(0, 10); + + return parseDateTime(datePart + "T12:00:00.000Z"); +} + +function getDateTimeForFile() { + return new Date().toISOString().substr(0, 19).replace(/:/g, ''); +} + +module.exports = { + nowDate, + dateStr, + parseDate, + parseDateTime, + getDateTimeForFile +}; \ No newline at end of file diff --git a/src/services/event_log.js b/src/services/event_log.js index 152a0e9f6..914a65b97 100644 --- a/src/services/event_log.js +++ b/src/services/event_log.js @@ -1,5 +1,5 @@ const sql = require('./sql'); -const utils = require('./utils'); +const dateUtils = require('./date_utils'); const log = require('./log'); async function addEvent(comment) { @@ -10,7 +10,7 @@ async function addNoteEvent(noteId, comment) { await sql.insert('event_log', { noteId : noteId, comment: comment, - dateAdded: utils.nowDate() + dateAdded: dateUtils.nowDate() }); log.info("Event log for " + noteId + ": " + comment); diff --git a/src/services/notes.js b/src/services/notes.js index e49150ef8..e6b7d3758 100644 --- a/src/services/notes.js +++ b/src/services/notes.js @@ -1,6 +1,6 @@ const sql = require('./sql'); const optionService = require('./options'); -const utils = require('./utils'); +const dateUtils = require('./date_utils'); const syncTableService = require('./sync_table'); const labelService = require('./labels'); const repository = require('./repository'); @@ -167,12 +167,12 @@ async function saveNoteRevision(note) { const now = new Date(); const noteRevisionSnapshotTimeInterval = parseInt(await optionService.getOption('note_revision_snapshot_time_interval')); - const revisionCutoff = utils.dateStr(new Date(now.getTime() - noteRevisionSnapshotTimeInterval * 1000)); + const revisionCutoff = dateUtils.dateStr(new Date(now.getTime() - noteRevisionSnapshotTimeInterval * 1000)); const existingnoteRevisionId = await sql.getValue( "SELECT noteRevisionId FROM note_revisions WHERE noteId = ? AND dateModifiedTo >= ?", [note.noteId, revisionCutoff]); - const msSinceDateCreated = now.getTime() - utils.parseDateTime(note.dateCreated).getTime(); + const msSinceDateCreated = now.getTime() - dateUtils.parseDateTime(note.dateCreated).getTime(); if (note.type !== 'file' && labelsMap.disable_versioning !== 'true' @@ -186,7 +186,7 @@ async function saveNoteRevision(note) { content: note.content, isProtected: 0, // will be fixed in the protectNoteRevisions() call dateModifiedFrom: note.dateModified, - dateModifiedTo: utils.nowDate() + dateModifiedTo: dateUtils.nowDate() })).save(); } } diff --git a/src/services/options.js b/src/services/options.js index e661dfc54..5f41d579d 100644 --- a/src/services/options.js +++ b/src/services/options.js @@ -1,5 +1,6 @@ const sql = require('./sql'); const utils = require('./utils'); +const dateUtils = require('./date_utils'); const syncTableService = require('./sync_table'); const appInfo = require('./app_info'); @@ -29,7 +30,7 @@ async function setOption(name, value) { } await sql.execute("UPDATE options SET value = ?, dateModified = ? WHERE name = ?", - [value, utils.nowDate(), name]); + [value, dateUtils.nowDate(), name]); } async function createOption(name, value, isSynced) { @@ -37,7 +38,7 @@ async function createOption(name, value, isSynced) { name: name, value: value, isSynced: isSynced, - dateModified: utils.nowDate() + dateModified: dateUtils.nowDate() }); if (isSynced) { @@ -59,7 +60,7 @@ async function initOptions(startNotePath) { await createOption('start_note_path', startNotePath, false); await createOption('protected_session_timeout', 600, true); await createOption('note_revision_snapshot_time_interval', 600, true); - await createOption('last_backup_date', utils.nowDate(), false); + await createOption('last_backup_date', dateUtils.nowDate(), false); await createOption('db_version', appInfo.db_version, false); await createOption('last_synced_pull', appInfo.db_version, false); diff --git a/src/services/script_context.js b/src/services/script_context.js index aa3f398c1..fb16b113c 100644 --- a/src/services/script_context.js +++ b/src/services/script_context.js @@ -2,6 +2,7 @@ const log = require('./log'); const noteService = require('./notes'); const sql = require('./sql'); const utils = require('./utils'); +const dateUtils = require('./date_utils'); const labelService = require('./labels'); const dateNoteService = require('./date_notes'); const config = require('./config'); @@ -34,8 +35,8 @@ function ScriptApi(startNote, currentNote) { this.utils = { unescapeHtml: utils.unescapeHtml, - isoDateTimeStr: utils.dateStr, - isoDateStr: date => utils.dateStr(date).substr(0, 10) + isoDateTimeStr: dateUtils.dateStr, + isoDateStr: date => dateUtils.dateStr(date).substr(0, 10) }; this.getInstanceName = () => config.General ? config.General.instanceName : null; diff --git a/src/services/source_id.js b/src/services/source_id.js index 4862ddf04..262c881d3 100644 --- a/src/services/source_id.js +++ b/src/services/source_id.js @@ -1,4 +1,5 @@ const utils = require('./utils'); +const dateUtils = require('./date_utils'); const log = require('./log'); const sql = require('./sql'); const cls = require('./cls'); @@ -6,7 +7,7 @@ const cls = require('./cls'); async function saveSourceId(sourceId) { await sql.insert("source_ids", { sourceId: sourceId, - dateCreated: utils.nowDate() + dateCreated: dateUtils.nowDate() }); await refreshSourceIds(); diff --git a/src/services/sync.js b/src/services/sync.js index e2f3d42bf..7b8df8b50 100644 --- a/src/services/sync.js +++ b/src/services/sync.js @@ -6,7 +6,7 @@ const sql = require('./sql'); const optionService = require('./options'); const utils = require('./utils'); const sourceIdService = require('./source_id'); -const noteService = require('./notes'); +const dateUtils = require('./date_utils'); const syncUpdateService = require('./sync_update'); const contentHashService = require('./content_hash'); const eventLogService = require('./event_log'); @@ -68,7 +68,7 @@ async function sync() { } async function login() { - const timestamp = utils.nowDate(); + const timestamp = dateUtils.nowDate(); const documentSecret = await optionService.getOption('document_secret'); const hash = utils.hmac(documentSecret, timestamp); diff --git a/src/services/sync_table.js b/src/services/sync_table.js index ca22530f5..eb6ef6d40 100644 --- a/src/services/sync_table.js +++ b/src/services/sync_table.js @@ -1,6 +1,6 @@ const sql = require('./sql'); const sourceIdService = require('./source_id'); -const utils = require('./utils'); +const dateUtils = require('./date_utils'); const syncSetup = require('./sync_setup'); const log = require('./log'); const cls = require('./cls'); @@ -49,7 +49,7 @@ async function addEntitySync(entityName, entityId, sourceId) { await sql.replace("sync", { entityName: entityName, entityId: entityId, - syncDate: utils.nowDate(), + syncDate: dateUtils.nowDate(), sourceId: sourceId || cls.getSourceId() || sourceIdService.getCurrentSourceId() }); @@ -84,7 +84,7 @@ async function fillSyncRows(entityName, entityKey) { entityName: entityName, entityId: entityId, sourceId: "SYNC_FILL", - syncDate: utils.nowDate() + syncDate: dateUtils.nowDate() }); } } diff --git a/src/services/utils.js b/src/services/utils.js index d9389624b..148361e26 100644 --- a/src/services/utils.js +++ b/src/services/utils.js @@ -16,41 +16,6 @@ function randomSecureToken(bytes = 32) { return crypto.randomBytes(bytes).toString('base64'); } -function nowDate() { - return dateStr(new Date()); -} - -function localDate() { - const date = new Date(); - - return date.getFullYear() + "-" - + (date.getMonth() < 9 ? "0" : "") + (date.getMonth() + 1) + "-" - + (date.getDate() < 10 ? "0" : "") + date.getDate(); -} - -function dateStr(date) { - return date.toISOString(); -} - -/** - * @param str - needs to be in the ISO 8601 format "YYYY-MM-DDTHH:MM:SS.sssZ" format as outputted by dateStr(). - * also is assumed to be GMT time (as indicated by the "Z" at the end), *not* local time - */ -function parseDateTime(str) { - try { - return new Date(Date.parse(str)); - } - catch (e) { - throw new Error("Can't parse date from " + str + ": " + e.stack); - } -} - -function parseDate(str) { - const datePart = str.substr(0, 10); - - return parseDateTime(datePart + "T12:00:00.000Z"); -} - function toBase64(plainText) { return Buffer.from(plainText).toString('base64'); } @@ -77,23 +42,11 @@ function isEmptyOrWhitespace(str) { return str === null || str.match(/^ *$/) !== null; } -function getDateTimeForFile() { - return new Date().toISOString().substr(0, 19).replace(/:/g, ''); -} - function sanitizeSql(str) { // should be improved or usage eliminated return str.replace(/'/g, "\\'"); } -function assertArguments() { - for (const i in arguments) { - if (!arguments[i]) { - throw new Error(`Argument idx#${i} should not be falsy: ${arguments[i]}`); - } - } -} - async function stopWatch(what, func) { const start = new Date(); @@ -125,11 +78,6 @@ function toObject(array, fn) { module.exports = { randomSecureToken, randomString, - nowDate, - localDate, - dateStr, - parseDate, - parseDateTime, newEntityId, toBase64, fromBase64, @@ -137,9 +85,7 @@ module.exports = { isElectron, hash, isEmptyOrWhitespace, - getDateTimeForFile, sanitizeSql, - assertArguments, stopWatch, unescapeHtml, toObject