diff --git a/dbInit/index.js b/dbInit/index.js index afa258a..7db0768 100644 --- a/dbInit/index.js +++ b/dbInit/index.js @@ -6,17 +6,17 @@ const dbInit = {}; const bulkData = [ { "index" : { "_index" : "changelog" } }, - { "author" : "John Ripper ", + { "author" : "John Ripper ", + { "author" : "John Ripper ", + { "author" : "John Ripper { diff --git a/public/css/site.css b/public/css/site.css index 10f4a7c..c4f874c 100644 --- a/public/css/site.css +++ b/public/css/site.css @@ -5,49 +5,45 @@ */ .log { - padding: 16px 0; - border-top: 1px solid #eee; + margin-bottom: 10px; + border-top: 1px solid #eee; + padding-top: 6px; +} +.log p { + color: #666; +} +.log span.cmd { + background: #eee; + color: #003e80; + padding: 3px 8px; +} +.log pre { + font-size: 1.0rem; + color: #333; } -.log .meta { +.log .meta a { + color: #666; font-size: .875rem; - color: #888; - line-height:1.2em; - text-align: right; - } - .log .meta p { - margin: 0px; - overflow: hidden; - text-overflow: ellipsis; + font-size: .875rem; + line-height:1em; + margin: 0px; + overflow: hidden; + text-overflow: ellipsis; } .log .meta p.server { - color: #333; - font-size:1.125rem; + color:#333; } .log .meta .actions-toggle { - margin: 0; - padding: 0; - cursor: pointer; - line-height:1em; + margin: 0; + padding: 0; + color: #666; + cursor: pointer; + line-height:1em; } .log .meta .actions{ display:none; } - -.log pre { - font-size: 1.125rem; - color: #333; -} -.log pre .cmd { - background: #eee; - color: #333f4d; - padding: 3px 8px; -} -@media (max-width: 991.98px){ -.log .meta { - text-align: left; -} - diff --git a/public/js/app.js b/public/js/app.js index f1eec74..0631fbe 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -1,195 +1,103 @@ /* global initData, authorizationToken */ -$(function(){ +// List of HTML entities for escaping. +var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '/': '/' +}; - const actionToggle = function(e){ - var el=e.target; - $(el).parent().siblings('.actions').show(); - $(el).hide(); - }; +// Regex containing the keys listed immediately above. +var htmlEscaper = /[&<>"'\/]/g; - const deleteButton = function(e){ - const el = $(e.target); - const url = el.attr('href'); - $.ajax(url,{ - method: "DELETE", - beforeSend: function(request) { - request.setRequestHeader("authorizationToken", authorizationToken); - } - }) - .done(function(data) { - $(el).parents('.log').remove(); - }) - .fail(function() { - alert( "error" ); - }); - return false; - }; - - const editButton = function(e){ - const el = $(e.target); - const id = el.attr("rel"); - const pre = el.parents(".log").find("pre"); - $.ajax(`/get/${id}`,{ - beforeSend: function(request) { - request.setRequestHeader("authorizationToken", authorizationToken); - } - }) - .done(function(data) { - pre - .text(data._source.content) - .attr('rel',id) - .css("background","#ccc") - .attr("contenteditable",true) - .focus(); - $('body pre[contenteditable]').on('focusout', contentEdited ); - - }) - .fail(function(data,err) { - console.log(data,err); - alert( "error" ); - }); - - return false; - }; - - const contentEdited = function(e) { - const el = $(e.target); - const id = el.attr('rel'); - const content = el.text(); - $.ajax(`/patch/${id}`,{ - method: "PATCH", - data: {content:content}, - beforeSend: function(request) { - request.setRequestHeader("authorizationToken", authorizationToken); - } - }) - .done(function(data) { - el - .css("background","") - .html( formatContent(content) ); - }) - .fail(function(data,err) { - console.log(data,err); - alert( "error" ); - }); - }; +// Escape a string for HTML interpolation. +escape = function(string) { + return ('' + string).replace(htmlEscaper, function(match) { + return htmlEscapes[match]; + }); +}; +var urlRegex = /(\S+): (https?://[^\s]+)/g; +url = function(string){ + return ''+string.replace(urlRegex, '$1') +} +var titleRegex = /^(.*\n)/; +title = function(string){ + return ''+string.replace(titleRegex, '$1'); +} +var cmdRegex = /```([^`]*?)```/g +cmd = function(string) { + return ''+string.replace(cmdRegex, '$1'); +} +date = function(date){ + var D = new Date(date); + return D.toLocaleDateString()+" "+D.toLocaleTimeString(); +} +function updatePage(data){ - const search = function(e){ - const el = $(e.target); - const val = el.val(); - if( val.length < 3 ){ return; } - $.ajax("/search",{ - beforeSend: function(request) { - request.setRequestHeader("authorizationToken", authorizationToken); - }, - data: { - q:val - } - }) - .done(function(data) { - updatePage(data); - }) - .fail(function() { - alert( "error" ); - }); - }; - - // List of HTML entities for escaping. - var htmlEscapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '/': '/' - }; - - // Regex containing the keys listed immediately above. - var htmlEscaper = /[&<>"'\/]/g; - - // Escape a string for HTML interpolation. - const escape = function(string) { - return ('' + string).replace(htmlEscaper, function(match) { - return htmlEscapes[match]; - }); - }; - const urlRegex = /(\S+): (https?://[^\s]+)/g; - const url = function(string){ - return ''+string.replace(urlRegex, '$1'); - }; - var titleRegex = /^(.*\n)/; - const title = function(string){ - return ''+string.replace(titleRegex, '$1'); - }; - var cmdRegex = /```([^`]*?)```/g; - const cmd = function(string) { - return ''+string.replace(cmdRegex, '$1'); - }; - const date = function(string){ - var D = new Date(string); - return D.toLocaleDateString()+" "+D.toLocaleTimeString(); - }; - const mailRegexp = /(.*) <(.+@.+)>/; - const mail = function( string ){ - return ''+string.replace(mailRegexp, `$1`); - }; - - const formatContent = function(string){ - return cmd(title(url(escape(string)))); - }; - - - function updatePage(data){ - - var content = ""; - var item = {}; - var id = ''; - // If the log entry is unique, simulate a search result - if( ! data['hits'] ){ - data = {hits:{hits:[data]}}; - } - $.each(data.hits.hits, (k,v)=>{ - - item = v._source; - id = v._id; - content += ` - -
-
-

${escape(item.server)}

- - ${date(escape(item.created_at))}
-
-
-

${mail(escape(item.author))}

-

- Actions -

-
- Remove - Edit -
-
-
-
-
 ${formatContent(item.content)}
-
-
- `; - }); - $("#content").html(content); - - // attache events - $(".actions-toggle").on("click",actionToggle ); - $('.delete').on('click', deleteButton); - $('.edit').on('click', editButton ); - + var content = ""; + var item = {}; + var id = ''; + // If the log entry is unique, simulate a search result + if( ! data['hits'] ){ + data = {hits:{hits:[data]}}; } + $.each(data.hits.hits, (k,v)=>{ + + item = v._source; + id = v._id; + content += ` - $("input").on("keyup",search ); - - updatePage( initData ); - +
+
+

${escape(item.server)}

+ + ${date(escape(item.created_at))}
+
+
+

${escape(item.author)}

+

+ Actions +

+
+ Remove + Edit +
+
+
+
+
 ${cmd(title(url(escape(item.content))))}
+
+
+ `; + }); + $("#content").html(content); + +} +$("input").on("keyup",function(e){ + const el = $(e.target); + const val = el.val(); + if( val.length < 3 ){ return; } + $.ajax("/search",{ + beforeSend: function(request) { + request.setRequestHeader("authorizationToken", authorizationToken); + }, + data: { + q:val, + } + }) + .done(function(data) { + updatePage(data); + }) + .fail(function() { + alert( "error" ); + }); }); + +updatePage( initData ); + +$(".actions-toggle").on("click",(e) => { var el=e.target; $(el).parent().siblings('.actions').show(); $(el).hide(); } ) + diff --git a/routes/index.js b/routes/index.js index f30b382..6514d2c 100644 --- a/routes/index.js +++ b/routes/index.js @@ -54,53 +54,6 @@ const routes = { res.json({"health":0,"msg":"Lost connection to ES"}); }); }, - delete: (req,res) => { - const id= req.params.id; - // Reindex the doc to the "trash" index - var log = client.reindex({ - refresh: true, - max_docs: 1, - body: { - source: { - index: 'changelog', - query: { - term: { - _id: id - } - } - }, - dest: { - index: 'changelog-trash', - } - } - }) - .then( (results, err) => { - - console.log(`reindexing success for id ${id}`) - // Remove it from the original index - return client.delete({ - index: "changelog", - id: id - }); - - }, (e) => { - - console.log("reindexing error") - res.status(400); - res.end("error"); - - }) - .then( (results, err) => { - - console.log(`Delete success for id ${id}`) - res.end("ok"); - - },(results, err) => { - console.log(`Delete error for id ${id}`) - res.status(400); - res.end("error"); - }); - }, add: (req, res) => { const body = req.body; @@ -116,43 +69,12 @@ const routes = { res.end("error"); }); } , - get: (req, res) => { - - const id= req.params.id; - var log = client.get({ - index: 'changelog', - id: id - }).then( (results, err) => { - res.json(results); - }, (e) => { - res.status(400); - res.json({msg:"Failed to get record"}); - }); - }, - patch: (req,res) => { - const id= req.params.id; - const content= req.body.content; - var log = client.update({ - - index: 'changelog', - id: id, - body:{ - doc:{ - content:content - } - } - }).then( (results, err) => { - res.json(results); - }, (e) => { - res.status(400); - res.json({msg:"Failed to get record"}); - }); }, log: (req, res) => { const id= req.params.id; var log = client.get({ index: 'changelog', - id: id + id: id }).then( (results, err) => { res.render('index', { title: 'changelog',