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) { return new Promise(function (resolve, reject) {
// if no content specified then use default note // if no content specified then use default note
if (!note.content) { if (!note.content) {
var body = null let filePath = config.defaultNotePath
let filePath = null
if (!note.alias) { if (note.alias) {
filePath = config.defaultNotePath const notePathInDocPath = path.join(config.docsPath, path.basename(note.alias) + '.md')
} else { if (Note.checkFileExist(notePathInDocPath)) {
filePath = path.join(config.docsPath, note.alias + '.md') filePath = notePathInDocPath
}
} }
if (Note.checkFileExist(filePath)) { if (Note.checkFileExist(filePath)) {
var fsCreatedTime = moment(fs.statSync(filePath).ctime) const noteInFS = readFileSystemNote(filePath)
body = fs.readFileSync(filePath, 'utf8') note.title = noteInFS.title
note.title = Note.parseNoteTitle(body) note.content = noteInFS.content
note.content = body
if (filePath !== config.defaultNotePath) { 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) { Note.parseNoteId = function (noteId, callback) {
async.series({ async.series({
parseNoteIdByAlias: function (_callback) { parseNoteIdByAlias: function (_callback) {
@ -204,65 +229,35 @@ module.exports = function (sequelize, DataTypes) {
where: { where: {
alias: noteId alias: noteId
} }
}).then(function (note) { }).then(async function (note) {
if (note) { const filePath = path.join(config.docsPath, path.basename(noteId) + '.md')
const filePath = path.join(config.docsPath, noteId + '.md') if (Note.checkFileExist(filePath)) {
if (Note.checkFileExist(filePath)) { try {
// if doc in filesystem have newer modified time than last change time if (note) {
// then will update the doc in db // if doc in filesystem have newer modified time than last change time
var fsModifiedTime = moment(fs.statSync(filePath).mtime) // then will update the doc in db
var dbModifiedTime = moment(note.lastchangeAt || note.createdAt) const noteInFS = readFileSystemNote(filePath)
var body = fs.readFileSync(filePath, 'utf8') if (shouldSyncNote(note, noteInFS)) {
var contentLength = body.length const noteId = await syncNote(noteInFS, note)
var title = Note.parseNoteTitle(body) return callback(null, noteId)
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)
})
} else { } 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) return callback(null, note.id)
} }
} else { } catch (err) {
return callback(null, note.id) return callback(err, null)
}
} 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)
} }
} }
if (!note) {
return callback(null, null)
}
return callback(null, note.id)
}).catch(function (err) { }).catch(function (err) {
return _callback(err, null) return _callback(err, null)
}) })
@ -589,5 +584,21 @@ module.exports = function (sequelize, DataTypes) {
return operations 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 return Note
} }

View File

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