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) { 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' }) return res.status(404).json({ status: 'error', message: 'Not found' })
} }
if (note.ownerId !== userId) { if (note.ownerId !== userId) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -84,7 +84,7 @@ export const getUIElements = () => ({
snippetImportSnippets: $('#snippetImportModalSnippets'), snippetImportSnippets: $('#snippetImportModalSnippets'),
revision: $('#revisionModal'), revision: $('#revisionModal'),
pandocExport: $('.pandoc-export-modal'), 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-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black"> <meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="mobile-web-app-capable" content="yes"> <meta name="mobile-web-app-capable" content="yes">
<meta name="note-alias" content="<%= alias %>">
<title><%= title %></title> <title><%= title %></title>
<link rel="icon" type="image/png" href="<%- serverURL %>/favicon.png"> <link rel="icon" type="image/png" href="<%- serverURL %>/favicon.png">
<link rel="apple-touch-icon" href="<%- serverURL %>/apple-touch-icon.png"> <link rel="apple-touch-icon" href="<%- serverURL %>/apple-touch-icon.png">

View File

@ -28,7 +28,7 @@
</li> </li>
<li class="divider"></li> <li class="divider"></li>
<li class="dropdown-header"><%= __('Extra') %></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>
<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 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> </li>
@ -134,7 +134,7 @@
</a> </a>
<ul class="dropdown-menu list" role="menu" aria-labelledby="menu"> <ul class="dropdown-menu list" role="menu" aria-labelledby="menu">
<li class="dropdown-header"><%= __('Extra') %></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>
<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 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> </li>

View File

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