added document_secret as basis for API authentication

This commit is contained in:
azivner 2017-10-28 19:55:55 -04:00
parent 724f4b43b7
commit eb6f9f8f81
7 changed files with 57 additions and 24 deletions

12
app.js
View File

@ -7,7 +7,9 @@ const helmet = require('helmet');
const session = require('express-session');
const FileStore = require('session-file-store')(session);
const os = require('os');
const sql = require('./services/sql');
const log = require('./services/log');
const utils = require('./services/utils');
const indexRoute = require('./routes/index');
const loginRoute = require('./routes/login');
@ -33,7 +35,15 @@ const db = require('sqlite');
const config = require('./services/config');
db.open(dataDir.DOCUMENT_PATH, { Promise });
db.open(dataDir.DOCUMENT_PATH, { Promise }).then(async () => {
if (!await sql.getOption('document_id')) {
await sql.setOption('document_id', utils.randomString(32));
}
if (!await sql.getOption('document_secret')) {
await sql.setOption('document_secret', utils.randomSecureToken(32));
}
});
const app = express();

View File

@ -0,0 +1 @@
INSERT INTO options (opt_name, opt_value) VALUES ('document_secret', '');

18
routes/api/login.js Normal file
View File

@ -0,0 +1,18 @@
"use strict";
const express = require('express');
const router = express.Router();
const auth = require('../../services/auth');
const sql = require('../../services/sql');
const migration = require('../../services/migration');
router.post('', async (req, res, next) => {
res.send({
'db_version': parseInt(await sql.getOption('db_version')),
'app_db_version': migration.APP_DB_VERSION
});
});
module.exports = router;

View File

@ -3,7 +3,7 @@ const sql = require('./sql');
const fs = require('fs-extra');
const log = require('./log');
const APP_DB_VERSION = 17;
const APP_DB_VERSION = 18;
const MIGRATIONS_DIR = "./migrations";
async function migrate() {

View File

@ -34,14 +34,13 @@ async function rollback() {
}
async function getOption(optName) {
try {
const row = await getSingleResult("SELECT opt_value FROM options WHERE opt_name = ?", [optName]);
const row = await getSingleResultOrNull("SELECT opt_value FROM options WHERE opt_name = ?", [optName]);
return row['opt_value'];
}
catch (e) {
if (!row) {
throw new Error("Option " + optName + " doesn't exist");
}
return row['opt_value'];
}
async function setOption(optName, optValue) {
@ -52,6 +51,12 @@ async function getSingleResult(query, params = []) {
return await db.get(query, ...params);
}
async function getSingleResultOrNull(query, params = []) {
const all = await db.all(query, ...params);
return all ? all[0] : null;
}
async function getResults(query, params = []) {
return await db.all(query, ...params);
}

View File

@ -149,7 +149,15 @@ async function putChanged(changed) {
}
async function putNote(note) {
await sql.insert("notes", note.detail, true);
const origNote = await sql.getSingleResult();
if (origNote !== null && origNote.date_modified >= note.detail.date_modified) {
// version we have in DB is actually newer than the one we're getting from sync
// so we'll leave the current state as it is. The synced version should be stored in the history
}
else {
await sql.insert("notes", note.detail, true);
}
await sql.remove("images", note.detail.note_id);
@ -168,22 +176,6 @@ async function putNote(note) {
log.info("Update/sync note " + note.detail.note_id);
}
let documentIdCache = null;
async function getDocumentId() {
if (!documentIdCache) {
documentIdCache = await sql.getOption('document_id');
if (!documentIdCache) {
documentIdCache = utils.randomString(16);
await sql.setOption('document_id', documentIdCache);
}
}
return documentIdCache;
}
if (SYNC_SERVER) {
log.info("Setting up sync");

View File

@ -1,5 +1,7 @@
"use strict";
const crypto = require('crypto');
function newNoteId() {
return randomString(12);
}
@ -16,6 +18,10 @@ function randomString(length) {
return result;
}
function randomSecureToken(bytes = 32) {
crypto.randomBytes(bytes).toString('base64');
}
function nowTimestamp() {
return Math.floor(Date.now() / 1000);
}
@ -29,6 +35,7 @@ function fromBase64(encodedText) {
}
module.exports = {
randomSecureToken,
randomString,
nowTimestamp,
newNoteId,