fix: multiple errors by custom note url

1. revert config refactoring
2. custom note url -> note alias
3. handle error in promise catch
4. adjust modal style
5. return 404 in change note alias api when note not found

Signed-off-by: Raccoon <raccoon@hackmd.io>
This commit is contained in:
Raccoon 2021-07-24 01:01:34 +08:00
parent 829c961a03
commit f76f7509e4
No known key found for this signature in database
GPG Key ID: 06770355DC9ECD38
10 changed files with 81 additions and 86 deletions

View File

@ -265,7 +265,7 @@ exports.updateNoteAlias = async (req, res) => {
if (!note) {
logger.error('update note alias failed: note not found.')
return res.status(500).json({ status: 'error', message: 'Internal Error' })
return res.status(404).json({ status: 'error', message: 'Not found' })
}
if (note.ownerId !== userId) {

View File

@ -79,7 +79,8 @@ function responseCodiMD (res, note) {
'X-Robots-Tag': 'noindex, nofollow' // prevent crawling
})
res.render('codimd.ejs', {
title: title
title: title,
alias: note.alias
})
}

View File

@ -118,6 +118,6 @@
"Register": "Register",
"Export with pandoc": "Export with pandoc",
"Select output format": "Select output format",
"Custom Note Url": "Custom Note Url",
"Note alias": "Note alias",
"Submit": "Submit"
}

View File

@ -118,6 +118,6 @@
"Register": "註冊",
"Export with pandoc": "使用 pandoc 匯出",
"Select output format": "選擇輸出格式",
"Custom Note Url": "自訂筆記網址",
"Note alias": "筆記別名",
"Submit": "送出"
}

View File

@ -26,7 +26,16 @@ import {
setloginStateChangeEvent
} from './lib/common/login'
import { getConfig } from './lib/config'
import {
debug,
DROPBOX_APP_KEY,
noteid,
noteurl,
noteAlias,
urlpath,
version,
updateNoteAliasConfig,
} from './lib/config'
import {
autoLinkify,
@ -84,24 +93,6 @@ require('spin.js/spin.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 viewportMargin = 20
var defaultEditorMode = 'gfm'
@ -1279,56 +1270,58 @@ $('#revisionModalRevert').click(function () {
})
// custom note url modal
const updateNoteUrl = (noteUrl = '') => {
const updateNoteAlias = (newAlias = '') => {
return new Promise((resolve, reject) => {
$.ajax({
method: 'PATCH',
url: `/api/notes/${noteid}/alias`,
data: JSON.stringify({
alias: noteUrl
}),
url: `/api/notes/${noteid}/alias`,
dataType: "json",
contentType: 'application/json;charset=utf-8',
data: JSON.stringify({
alias: newAlias
}),
success: resolve,
error: reject
})
})
}
ui.modal.customNoteUrl.on('submit', function (e) {
ui.modal.changeNoteAliasModal.on('show.bs.modal', function (e) {
ui.modal.changeNoteAliasModal.find('[name="note-alias"]').val(noteAlias)
})
ui.modal.changeNoteAliasModal.on('submit', function (e) {
e.preventDefault()
const showErrorMessage = (msg) => {
ui.modal.customNoteUrl.find('.js-error-message').text(msg)
ui.modal.customNoteUrl.find('.js-error-alert').show()
ui.modal.changeNoteAliasModal.find('.js-error-message').text(msg)
ui.modal.changeNoteAliasModal.find('.js-error-alert').show()
}
const hideErrorMessage = () => ui.modal.customNoteUrl.find('.js-error-alert').hide()
const hideErrorMessage = () => ui.modal.changeNoteAliasModal.find('.js-error-alert').hide()
const customUrl = ui.modal.customNoteUrl.find('[name="custom-url"]').val()
if (!/^[0-9a-z-_]+$/.test(customUrl)) {
const newNoteAlias = ui.modal.changeNoteAliasModal.find('[name="note-alias"]').val()
if (!/^[0-9a-z-_]+$/.test(newNoteAlias)) {
showErrorMessage('The url must be lowercase letters, decimal digits, hyphen or underscore.')
return
}
updateNoteUrl(customUrl)
updateNoteAlias(newNoteAlias)
.then(
({ status }) => {
if (status === 'ok') {
hideErrorMessage()
ui.modal.customNoteUrl.modal('hide')
ui.modal.changeNoteAliasModal.modal('hide')
}
},
err => {
if (err.status === 400 && err.responseJSON.message) {
showErrorMessage(err.responseJSON.message)
return
}
if (err.status === 403) {
showErrorMessage('Only note owner can edit custom url.')
return
}
showErrorMessage('Something wrong.')
}
)
.catch(() => {
.catch((err) => {
if (err.status === 400 && err.responseJSON.message) {
showErrorMessage(err.responseJSON.message)
return
}
if (err.status === 403) {
showErrorMessage('Only note owner can edit custom url.')
return
}
showErrorMessage('Something wrong.')
})
})
@ -2288,7 +2281,7 @@ socket.on('cursor blur', function (data) {
socket.on('alias updated', function (data) {
const alias = data.alias
history.replaceState({}, '', alias)
updateConfig()
updateNoteAliasConfig(alias)
})
var options = {

View File

@ -1,26 +1,26 @@
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 DROPBOX_APP_KEY = window.DROPBOX_APP_KEY || ''
export const domain = window.domain || '' // domain name
export const urlpath = window.urlpath || '' // sub url path, like: www.example.com/<urlpath>
export const debug = window.debug || false
export const port = window.location.port
export const serverurl = `${window.location.protocol}//${domain || window.location.hostname}${port ? ':' + port : ''}${urlpath ? '/' + urlpath : ''}`
window.serverurl = serverurl
export let noteid = ''
export let noteurl = ''
export let noteAlias = document.querySelector("meta[name='note-alias']").getAttribute('content')
export function updateNoteAliasConfig (alias) {
noteAlias = alias
document.querySelector("meta[name='note-alias']").setAttribute('content', noteAlias)
refreshNoteUrlConfig()
}
const config = getConfig()
window.serverurl = config.serverurl
export function refreshNoteUrlConfig () {
noteid = decodeURIComponent(urlpath ? window.location.pathname.slice(urlpath.length + 1, window.location.pathname.length).split('/')[1] : window.location.pathname.split('/')[1])
noteurl = `${serverurl}/${noteid}`
}
export const DROPBOX_APP_KEY = config.DROPBOX_APP_KEY
export const domain = config.domain
export const urlpath = config.urlpath
export const debug = config.debug
export const port = config.port
export const serverurl = config.serverurl
export const noteid = config.noteid
export const noteurl = config.noteurl
export const version = config.version
refreshNoteUrlConfig()
export const version = window.version

View File

@ -84,7 +84,7 @@ export const getUIElements = () => ({
snippetImportSnippets: $('#snippetImportModalSnippets'),
revision: $('#revisionModal'),
pandocExport: $('.pandoc-export-modal'),
customNoteUrl: $('#customNoteUrlModal')
changeNoteAliasModal: $('#noteAliasModal')
}
})

View File

@ -4,6 +4,7 @@
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="mobile-web-app-capable" content="yes">
<meta name="note-alias" content="<%= alias %>">
<title><%= title %></title>
<link rel="icon" type="image/png" href="<%- serverURL %>/favicon.png">
<link rel="apple-touch-icon" href="<%- serverURL %>/apple-touch-icon.png">

View File

@ -28,7 +28,7 @@
</li>
<li class="divider"></li>
<li class="dropdown-header"><%= __('Extra') %></li>
<li role="presentation"><a role="menuitem" class="ui-extra-revision" tabindex="-1" data-toggle="modal" data-target="#customNoteUrlModal"><i class="fa fa-pencil-square-o fa-fw"></i> <%= __('Custom Note Url') %></a>
<li role="presentation"><a role="menuitem" class="ui-extra-revision" tabindex="-1" data-toggle="modal" data-target="#noteAliasModal"><i class="fa fa-pencil-square-o fa-fw"></i> <%= __('Note alias') %></a>
</li>
<li role="presentation"><a role="menuitem" class="ui-extra-revision" tabindex="-1" data-toggle="modal" data-target="#revisionModal"><i class="fa fa-history fa-fw"></i> <%= __('Revision') %></a>
</li>
@ -134,7 +134,7 @@
</a>
<ul class="dropdown-menu list" role="menu" aria-labelledby="menu">
<li class="dropdown-header"><%= __('Extra') %></li>
<li role="presentation"><a role="menuitem" class="ui-extra-revision" tabindex="-1" data-toggle="modal" data-target="#customNoteUrlModal"><i class="fa fa-pencil-square-o fa-fw"></i> <%= __('Custom Note Url') %></a>
<li role="presentation"><a role="menuitem" class="ui-extra-revision" tabindex="-1" data-toggle="modal" data-target="#noteAliasModal"><i class="fa fa-pencil-square-o fa-fw"></i> <%= __('Note alias') %></a>
</li>
<li role="presentation"><a role="menuitem" class="ui-extra-revision" tabindex="-1" data-toggle="modal" data-target="#revisionModal"><i class="fa fa-history fa-fw"></i> <%= __('Revision') %></a>
</li>

View File

@ -1,6 +1,6 @@
<!-- custom-note-url-modal -->
<div class="modal fade" id="customNoteUrlModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal fade" id="noteAliasModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-md">
<div class="modal-content">
<form role="form">
<div class="modal-header">
@ -8,28 +8,28 @@
aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title"><i class="fa fa-pencil-square-o"></i>
<%= __('Custom Note Url') %>
<%= __('Note alias') %>
</h4>
</div>
<div class="modal-body">
<div class="form-group">
<div class="alert alert-warning" role="alert">
<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></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>
<span>Notice: the previous note alias 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>
<p>For example: /hello-world</p>
<input type="text" class="form-control" name="custom-url" placeholder="hello-world" required>
<p>For example: hello-world</p>
<input type="text" class="form-control" name="note-alias" placeholder="hello-world" value="<%= alias %>" required>
<div class="help-block with-errors"></div>
</div>
<div class="form-group text-right">
<button type="submit" class="btn btn-primary" style="margin-left: auto;">
<%= __('Submit') %>
</button>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary" style="margin-left: auto;">
<%= __('Submit') %>
</button>
</div>
</form>
</div>