mirror of https://github.com/status-im/codimd.git
revmoe archivedAlias logic
Signed-off-by: nick.chen <nick.chen.sudo@gmail.com>
This commit is contained in:
parent
014790a8eb
commit
d72d6a0f7a
|
@ -1,32 +0,0 @@
|
||||||
'use strict'
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
up: function (queryInterface, Sequelize) {
|
|
||||||
return queryInterface.createTable('ArchivedNoteAliases', {
|
|
||||||
id: {
|
|
||||||
type: Sequelize.UUID,
|
|
||||||
primaryKey: true,
|
|
||||||
defaultValue: Sequelize.UUIDV4
|
|
||||||
},
|
|
||||||
noteId: Sequelize.UUID,
|
|
||||||
alias: {
|
|
||||||
type: Sequelize.STRING,
|
|
||||||
allowNull: false,
|
|
||||||
unique: true
|
|
||||||
},
|
|
||||||
createdAt: Sequelize.DATE,
|
|
||||||
updatedAt: Sequelize.DATE
|
|
||||||
})
|
|
||||||
.then(
|
|
||||||
() => queryInterface.addIndex(
|
|
||||||
'ArchivedNoteAliases',
|
|
||||||
['alias'], {
|
|
||||||
unique: true
|
|
||||||
})
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|
|
||||||
down: function (queryInterface) {
|
|
||||||
return queryInterface.dropTable('ArchivedNoteAliases')
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
'use strict'
|
|
||||||
// external modules
|
|
||||||
const Sequelize = require('sequelize')
|
|
||||||
|
|
||||||
module.exports = function (sequelize, DataTypes) {
|
|
||||||
const ArchivedNoteAlias = sequelize.define('ArchivedNoteAlias', {
|
|
||||||
id: {
|
|
||||||
type: DataTypes.UUID,
|
|
||||||
primaryKey: true,
|
|
||||||
defaultValue: Sequelize.UUIDV4
|
|
||||||
},
|
|
||||||
noteId: {
|
|
||||||
type: DataTypes.UUID
|
|
||||||
},
|
|
||||||
alias: {
|
|
||||||
type: DataTypes.STRING,
|
|
||||||
unique: true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
ArchivedNoteAlias.associate = function (models) {
|
|
||||||
ArchivedNoteAlias.belongsTo(models.Note, {
|
|
||||||
foreignKey: 'noteId',
|
|
||||||
as: 'note',
|
|
||||||
constraints: false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
return ArchivedNoteAlias
|
|
||||||
}
|
|
|
@ -157,11 +157,6 @@ module.exports = function (sequelize, DataTypes) {
|
||||||
as: 'authors',
|
as: 'authors',
|
||||||
constraints: false
|
constraints: false
|
||||||
})
|
})
|
||||||
Note.hasMany(models.ArchivedNoteAlias, {
|
|
||||||
foreignKey: 'noteId',
|
|
||||||
as: 'archivedAlias',
|
|
||||||
constraints: false
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
Note.checkFileExist = function (filePath) {
|
Note.checkFileExist = function (filePath) {
|
||||||
try {
|
try {
|
||||||
|
@ -228,18 +223,6 @@ module.exports = function (sequelize, DataTypes) {
|
||||||
|
|
||||||
Note.parseNoteId = function (noteId, callback) {
|
Note.parseNoteId = function (noteId, callback) {
|
||||||
async.series({
|
async.series({
|
||||||
parseNoteIdByArchivedAlias: function (_callback) {
|
|
||||||
sequelize.models.ArchivedNoteAlias.findOne({
|
|
||||||
where: {
|
|
||||||
alias: noteId
|
|
||||||
}
|
|
||||||
}).then(function (archivedAlias) {
|
|
||||||
if (!archivedAlias) {
|
|
||||||
return _callback(null, null)
|
|
||||||
}
|
|
||||||
return callback(null, archivedAlias.noteId)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
parseNoteIdByAlias: function (_callback) {
|
parseNoteIdByAlias: function (_callback) {
|
||||||
// try to parse note id by alias (e.g. doc)
|
// try to parse note id by alias (e.g. doc)
|
||||||
Note.findOne({
|
Note.findOne({
|
||||||
|
|
|
@ -265,6 +265,7 @@ exports.updateNoteAlias = async (req, res) => {
|
||||||
|
|
||||||
if (!note) {
|
if (!note) {
|
||||||
logger.error('update note alias failed: note not found.')
|
logger.error('update note alias failed: note not found.')
|
||||||
|
return res.status(500).json({ status: 'error', message: 'Internal Error' })
|
||||||
}
|
}
|
||||||
|
|
||||||
if (note.ownerId !== userId) {
|
if (note.ownerId !== userId) {
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
|
|
||||||
'use strict'
|
'use strict'
|
||||||
const { Note, User, ArchivedNoteAlias, sequelize } = require('../models')
|
const { Note, User } = require('../models')
|
||||||
const config = require('../config')
|
const config = require('../config')
|
||||||
const logger = require('../logger')
|
const logger = require('../logger')
|
||||||
const realtime = require('../realtime/realtime')
|
const realtime = require('../realtime/realtime')
|
||||||
|
const { updateHistory } = require('../history')
|
||||||
|
|
||||||
const EXIST_WEB_ROUTES = ['', 'new', 'me', 'history', '403', '404', '500', 'config']
|
const EXIST_WEB_ROUTES = ['', 'new', 'me', 'history', '403', '404', '500', 'config']
|
||||||
const FORBIDDEN_ALIASES = [...EXIST_WEB_ROUTES, ...config.forbiddenNoteIDs]
|
const FORBIDDEN_ALIASES = [...EXIST_WEB_ROUTES, ...config.forbiddenNoteIDs]
|
||||||
|
@ -32,6 +33,23 @@ exports.getNote = async (originAliasOrNoteId, { includeUser } = { includeUser: f
|
||||||
return note
|
return note
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exports.createNote = async (userId, noteAlias) => {
|
||||||
|
if (!config.allowAnonymous && !userId) {
|
||||||
|
throw new Error('can not create note')
|
||||||
|
}
|
||||||
|
|
||||||
|
const note = await Note.create({
|
||||||
|
ownerId: userId,
|
||||||
|
alias: noteAlias
|
||||||
|
})
|
||||||
|
|
||||||
|
if (userId) {
|
||||||
|
updateHistory(userId, note)
|
||||||
|
}
|
||||||
|
|
||||||
|
return note
|
||||||
|
}
|
||||||
|
|
||||||
exports.canViewNote = (note, isLogin, userId) => {
|
exports.canViewNote = (note, isLogin, userId) => {
|
||||||
if (note.permission === 'private') {
|
if (note.permission === 'private') {
|
||||||
return note.ownerId === userId
|
return note.ownerId === userId
|
||||||
|
@ -91,10 +109,7 @@ const checkAliasValid = async (originAliasOrNoteId, alias) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const conflictNote = await exports.getNote(alias)
|
const conflictNote = await exports.getNote(alias)
|
||||||
.catch((err) => { throw err })
|
|
||||||
|
|
||||||
const note = await exports.getNote(originAliasOrNoteId)
|
const note = await exports.getNote(originAliasOrNoteId)
|
||||||
.catch((err) => { throw err })
|
|
||||||
|
|
||||||
if (conflictNote && conflictNote.id !== note.id) {
|
if (conflictNote && conflictNote.id !== note.id) {
|
||||||
return {
|
return {
|
||||||
|
@ -111,8 +126,6 @@ const checkAliasValid = async (originAliasOrNoteId, alias) => {
|
||||||
exports.updateAlias = async (originAliasOrNoteId, alias) => {
|
exports.updateAlias = async (originAliasOrNoteId, alias) => {
|
||||||
const sanitizedAlias = sanitizeAlias(alias)
|
const sanitizedAlias = sanitizeAlias(alias)
|
||||||
const note = await exports.getNote(originAliasOrNoteId)
|
const note = await exports.getNote(originAliasOrNoteId)
|
||||||
.catch((err) => { throw err })
|
|
||||||
|
|
||||||
const { isValid, errorMessage } = await checkAliasValid(originAliasOrNoteId, alias)
|
const { isValid, errorMessage } = await checkAliasValid(originAliasOrNoteId, alias)
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
return {
|
return {
|
||||||
|
@ -121,38 +134,11 @@ exports.updateAlias = async (originAliasOrNoteId, alias) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const t = await sequelize.transaction()
|
|
||||||
if (note.alias) {
|
|
||||||
const archivedAlias = await ArchivedNoteAlias.findOne({
|
|
||||||
where: {
|
|
||||||
alias: note.alias
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch(async err => { throw err })
|
|
||||||
|
|
||||||
if (!archivedAlias) {
|
|
||||||
await ArchivedNoteAlias.create({
|
|
||||||
noteId: note.id,
|
|
||||||
alias: note.alias
|
|
||||||
}, { transaction: t })
|
|
||||||
.catch(async err => {
|
|
||||||
await t.rollback()
|
|
||||||
throw Error('Add archived note alias failed. ' + err.message)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const updatedNote = await note.update({
|
const updatedNote = await note.update({
|
||||||
alias: sanitizedAlias,
|
alias: sanitizedAlias,
|
||||||
lastchangeAt: Date.now()
|
lastchangeAt: Date.now()
|
||||||
}, { transaction: t })
|
|
||||||
.catch(async err => {
|
|
||||||
await t.rollback()
|
|
||||||
throw Error('Write note content error. ' + err.message)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
await t.commit()
|
|
||||||
|
|
||||||
realtime.io.to(updatedNote.id)
|
realtime.io.to(updatedNote.id)
|
||||||
.emit('alias updated', {
|
.emit('alias updated', {
|
||||||
alias: updatedNote.alias
|
alias: updatedNote.alias
|
||||||
|
|
|
@ -26,14 +26,7 @@ import {
|
||||||
setloginStateChangeEvent
|
setloginStateChangeEvent
|
||||||
} from './lib/common/login'
|
} from './lib/common/login'
|
||||||
|
|
||||||
import {
|
import { getConfig } from './lib/config'
|
||||||
debug,
|
|
||||||
DROPBOX_APP_KEY,
|
|
||||||
noteid,
|
|
||||||
noteurl,
|
|
||||||
urlpath,
|
|
||||||
version
|
|
||||||
} from './lib/config'
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
autoLinkify,
|
autoLinkify,
|
||||||
|
@ -91,6 +84,24 @@ require('spin.js/spin.css')
|
||||||
|
|
||||||
require('highlight.js/styles/github-gist.css')
|
require('highlight.js/styles/github-gist.css')
|
||||||
|
|
||||||
|
let debug,
|
||||||
|
DROPBOX_APP_KEY,
|
||||||
|
noteid,
|
||||||
|
noteurl,
|
||||||
|
urlpath,
|
||||||
|
version
|
||||||
|
|
||||||
|
function updateConfig () {
|
||||||
|
const config = getConfig()
|
||||||
|
debug = config.debug
|
||||||
|
DROPBOX_APP_KEY = config.DROPBOX_APP_KEY
|
||||||
|
noteid = config.noteid
|
||||||
|
noteurl = config.noteurl
|
||||||
|
urlpath = config.urlpath
|
||||||
|
version = config.version
|
||||||
|
}
|
||||||
|
updateConfig()
|
||||||
|
|
||||||
var defaultTextHeight = 20
|
var defaultTextHeight = 20
|
||||||
var viewportMargin = 20
|
var viewportMargin = 20
|
||||||
var defaultEditorMode = 'gfm'
|
var defaultEditorMode = 'gfm'
|
||||||
|
@ -1286,10 +1297,10 @@ const updateNoteUrl = (noteUrl = '') => {
|
||||||
ui.modal.customNoteUrl.on('submit', function (e) {
|
ui.modal.customNoteUrl.on('submit', function (e) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
const showErrorMessage = (msg) => {
|
const showErrorMessage = (msg) => {
|
||||||
ui.modal.customNoteUrl.find('.error-message').text(msg)
|
ui.modal.customNoteUrl.find('.js-error-message').text(msg)
|
||||||
ui.modal.customNoteUrl.find('.alert').show()
|
ui.modal.customNoteUrl.find('.js-error-alert').show()
|
||||||
}
|
}
|
||||||
const hideErrorMessage = () => ui.modal.customNoteUrl.find('.alert').hide()
|
const hideErrorMessage = () => ui.modal.customNoteUrl.find('.js-error-alert').hide()
|
||||||
|
|
||||||
const customUrl = ui.modal.customNoteUrl.find('[name="custom-url"]').val()
|
const customUrl = ui.modal.customNoteUrl.find('[name="custom-url"]').val()
|
||||||
if (!/^[0-9a-z-_]+$/.test(customUrl)) {
|
if (!/^[0-9a-z-_]+$/.test(customUrl)) {
|
||||||
|
@ -1306,7 +1317,6 @@ ui.modal.customNoteUrl.on('submit', function (e) {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
err => {
|
err => {
|
||||||
console.log(err)
|
|
||||||
if (err.status === 400 && err.responseJSON.message) {
|
if (err.status === 400 && err.responseJSON.message) {
|
||||||
showErrorMessage(err.responseJSON.message)
|
showErrorMessage(err.responseJSON.message)
|
||||||
return
|
return
|
||||||
|
@ -2278,6 +2288,7 @@ socket.on('cursor blur', function (data) {
|
||||||
socket.on('alias updated', function (data) {
|
socket.on('alias updated', function (data) {
|
||||||
const alias = data.alias
|
const alias = data.alias
|
||||||
history.replaceState({}, '', alias)
|
history.replaceState({}, '', alias)
|
||||||
|
updateConfig()
|
||||||
})
|
})
|
||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
|
|
|
@ -1,13 +1,26 @@
|
||||||
export const DROPBOX_APP_KEY = window.DROPBOX_APP_KEY || ''
|
export function getConfig () {
|
||||||
|
return {
|
||||||
|
DROPBOX_APP_KEY: window.DROPBOX_APP_KEY || '',
|
||||||
|
domain: window.domain || '',
|
||||||
|
urlpath: window.urlpath || '',
|
||||||
|
debug: window.debug || false,
|
||||||
|
serverurl: `${window.location.protocol}//${domain || window.location.hostname}${port ? ':' + port : ''}${urlpath ? '/' + urlpath : ''}`,
|
||||||
|
port: window.location.port,
|
||||||
|
noteid: decodeURIComponent(urlpath ? window.location.pathname.slice(urlpath.length + 1, window.location.pathname.length).split('/')[1] : window.location.pathname.split('/')[1]),
|
||||||
|
noteurl: `${serverurl}/${noteid}`,
|
||||||
|
version: window.version
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export const domain = window.domain || '' // domain name
|
const config = getConfig()
|
||||||
export const urlpath = window.urlpath || '' // sub url path, like: www.example.com/<urlpath>
|
window.serverurl = config.serverurl
|
||||||
export const debug = window.debug || false
|
|
||||||
|
|
||||||
export const port = window.location.port
|
export const DROPBOX_APP_KEY = config.DROPBOX_APP_KEY
|
||||||
export const serverurl = `${window.location.protocol}//${domain || window.location.hostname}${port ? ':' + port : ''}${urlpath ? '/' + urlpath : ''}`
|
export const domain = config.domain
|
||||||
window.serverurl = serverurl
|
export const urlpath = config.urlpath
|
||||||
export const noteid = decodeURIComponent(urlpath ? window.location.pathname.slice(urlpath.length + 1, window.location.pathname.length).split('/')[1] : window.location.pathname.split('/')[1])
|
export const debug = config.debug
|
||||||
export const noteurl = `${serverurl}/${noteid}`
|
export const port = config.port
|
||||||
|
export const serverurl = config.serverurl
|
||||||
export const version = window.version
|
export const noteid = config.noteid
|
||||||
|
export const noteurl = config.noteurl
|
||||||
|
export const version = config.version
|
||||||
|
|
|
@ -13,9 +13,13 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<div class="alert alert-danger" style="display: none" role="alert">
|
<div class="alert alert-warning" role="alert">
|
||||||
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
|
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
|
||||||
<span class="error-message"></span>
|
<span>Notice: the previous custom note url will not be redirected to the new one, please take your own risk to change this.</span>
|
||||||
|
</div>
|
||||||
|
<div class="alert alert-danger js-error-alert" style="display: none" role="alert">
|
||||||
|
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
|
||||||
|
<span class="js-error-message"></span>
|
||||||
</div>
|
</div>
|
||||||
<p>For example: /hello-world</p>
|
<p>For example: /hello-world</p>
|
||||||
<input type="text" class="form-control" name="custom-url" placeholder="hello-world" required>
|
<input type="text" class="form-control" name="custom-url" placeholder="hello-world" required>
|
||||||
|
|
Loading…
Reference in New Issue