Merge pull request #1674 from hackmdio/fix/free-url-can-read-any-md-in-file-system

Fix/free url can read any md in file system
This commit is contained in:
Yukai Huang 2021-05-11 15:29:35 +08:00 committed by GitHub
commit 2467fce638
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 78 additions and 65 deletions

View File

@ -92,20 +92,22 @@ module.exports = function (sequelize, DataTypes) {
return new Promise(function (resolve, reject) {
// if no content specified then use default note
if (!note.content) {
var body = null
let filePath = null
if (!note.alias) {
filePath = config.defaultNotePath
} else {
filePath = path.join(config.docsPath, note.alias + '.md')
let filePath = config.defaultNotePath
if (note.alias) {
const notePathInDocPath = path.join(config.docsPath, path.basename(note.alias) + '.md')
if (Note.checkFileExist(notePathInDocPath)) {
filePath = notePathInDocPath
}
}
if (Note.checkFileExist(filePath)) {
var fsCreatedTime = moment(fs.statSync(filePath).ctime)
body = fs.readFileSync(filePath, 'utf8')
note.title = Note.parseNoteTitle(body)
note.content = body
const noteInFS = readFileSystemNote(filePath)
note.title = noteInFS.title
note.content = noteInFS.content
if (filePath !== config.defaultNotePath) {
note.createdAt = fsCreatedTime
note.createdAt = noteInFS.lastchangeAt
note.lastchangeAt = noteInFS.lastchangeAt
}
}
}
@ -196,6 +198,29 @@ module.exports = function (sequelize, DataTypes) {
})
})
}
async function syncNote (noteInFS, note) {
const contentLength = noteInFS.content.length
let note2 = await note.update({
title: noteInFS.title,
content: noteInFS.content,
lastchangeAt: noteInFS.lastchangeAt
})
const revision = await sequelize.models.Revision.saveNoteRevisionAsync(note2)
// update authorship on after making revision of docs
const patch = dmp.patch_fromText(revision.patch)
const operations = Note.transformPatchToOperations(patch, contentLength)
let authorship = note2.authorship
for (let i = 0; i < operations.length; i++) {
authorship = Note.updateAuthorshipByOperation(operations[i], null, authorship)
}
note2 = await note.update({
authorship: authorship
})
return note2.id
}
Note.parseNoteId = function (noteId, callback) {
async.series({
parseNoteIdByAlias: function (_callback) {
@ -204,65 +229,35 @@ module.exports = function (sequelize, DataTypes) {
where: {
alias: noteId
}
}).then(function (note) {
if (note) {
const filePath = path.join(config.docsPath, noteId + '.md')
if (Note.checkFileExist(filePath)) {
// if doc in filesystem have newer modified time than last change time
// then will update the doc in db
var fsModifiedTime = moment(fs.statSync(filePath).mtime)
var dbModifiedTime = moment(note.lastchangeAt || note.createdAt)
var body = fs.readFileSync(filePath, 'utf8')
var contentLength = body.length
var title = Note.parseNoteTitle(body)
if (fsModifiedTime.isAfter(dbModifiedTime) && note.content !== body) {
note.update({
title: title,
content: body,
lastchangeAt: fsModifiedTime
}).then(function (note) {
sequelize.models.Revision.saveNoteRevision(note, function (err, revision) {
if (err) return _callback(err, null)
// update authorship on after making revision of docs
var patch = dmp.patch_fromText(revision.patch)
var operations = Note.transformPatchToOperations(patch, contentLength)
var authorship = note.authorship
for (let i = 0; i < operations.length; i++) {
authorship = Note.updateAuthorshipByOperation(operations[i], null, authorship)
}
note.update({
authorship: authorship
}).then(function (note) {
return callback(null, note.id)
}).catch(function (err) {
return _callback(err, null)
})
})
}).catch(function (err) {
return _callback(err, null)
})
}).then(async function (note) {
const filePath = path.join(config.docsPath, path.basename(noteId) + '.md')
if (Note.checkFileExist(filePath)) {
try {
if (note) {
// if doc in filesystem have newer modified time than last change time
// then will update the doc in db
const noteInFS = readFileSystemNote(filePath)
if (shouldSyncNote(note, noteInFS)) {
const noteId = await syncNote(noteInFS, note)
return callback(null, noteId)
}
} else {
// create new note with alias, and will sync md file in beforeCreateHook
const note = await Note.create({
alias: noteId,
owner: null,
permission: 'locked'
})
return callback(null, note.id)
}
} else {
return callback(null, note.id)
}
} else {
var filePath = path.join(config.docsPath, noteId + '.md')
if (Note.checkFileExist(filePath)) {
Note.create({
alias: noteId,
owner: null,
permission: 'locked'
}).then(function (note) {
return callback(null, note.id)
}).catch(function (err) {
return _callback(err, null)
})
} else {
return _callback(null, null)
} catch (err) {
return callback(err, null)
}
}
if (!note) {
return callback(null, null)
}
return callback(null, note.id)
}).catch(function (err) {
return _callback(err, null)
})
@ -589,5 +584,21 @@ module.exports = function (sequelize, DataTypes) {
return operations
}
function readFileSystemNote (filePath) {
const fsModifiedTime = moment(fs.statSync(filePath).mtime)
const content = fs.readFileSync(filePath, 'utf8')
return {
lastchangeAt: fsModifiedTime,
title: Note.parseNoteTitle(content),
content: content
}
}
function shouldSyncNote (note, noteInFS) {
const dbModifiedTime = moment(note.lastchangeAt || note.createdAt)
return noteInFS.lastchangeAt.isAfter(dbModifiedTime) && note.content !== noteInFS.content
}
return Note
}

View File

@ -6,6 +6,7 @@ var moment = require('moment')
var childProcess = require('child_process')
var shortId = require('shortid')
var path = require('path')
var util = require('util')
var Op = Sequelize.Op
@ -296,6 +297,7 @@ module.exports = function (sequelize, DataTypes) {
return callback(err, null)
})
}
Revision.saveNoteRevisionAsync = util.promisify(Revision.saveNoteRevision)
Revision.finishSaveNoteRevision = function (note, revision, callback) {
note.update({
savedAt: revision.updatedAt