2018-05-15 17:36:45 +00:00
/ * *
* @ author n1474335 [ n1474335 @ gmail . com ]
* @ copyright Crown Copyright 2016
* @ license Apache - 2.0
* /
2019-07-09 12:23:59 +01:00
import HTMLIngredient from "./HTMLIngredient.mjs" ;
2021-02-10 13:13:19 +00:00
import Utils from "../core/Utils.mjs" ;
2021-02-10 17:41:39 +00:00
import url from "url" ;
2018-05-15 17:36:45 +00:00
/ * *
* Object to handle the creation of operations .
* /
class HTMLOperation {
/ * *
* HTMLOperation constructor .
*
* @ param { string } name - The name of the operation .
* @ param { Object } config - The configuration object for this operation .
* @ param { App } app - The main view object for CyberChef .
* @ param { Manager } manager - The CyberChef event manager .
* /
constructor ( name , config , app , manager ) {
this . app = app ;
this . manager = manager ;
this . name = name ;
this . description = config . description ;
2018-08-21 19:07:13 +01:00
this . infoURL = config . infoURL ;
2018-05-15 17:36:45 +00:00
this . manualBake = config . manualBake || false ;
this . config = config ;
this . ingList = [ ] ;
for ( let i = 0 ; i < config . args . length ; i ++ ) {
const ing = new HTMLIngredient ( config . args [ i ] , this . app , this . manager ) ;
this . ingList . push ( ing ) ;
}
}
/ * *
* Renders the operation in HTML as a stub operation with no ingredients .
*
* @ returns { string }
* /
toStubHtml ( removeIcon ) {
let html = "<li class='operation'" ;
if ( this . description ) {
2018-08-21 19:07:13 +01:00
const infoLink = this . infoURL ? ` <hr> ${ titleFromWikiLink ( this . infoURL ) } ` : "" ;
2018-06-09 10:43:36 +01:00
html += ` data-container='body' data-toggle='popover' data-placement='right'
2018-08-21 19:07:13 +01:00
data - content = "${this.description}${infoLink}" data - html = 'true' data - trigger = 'hover'
2018-06-09 10:43:36 +01:00
data - boundary = 'viewport' ` ;
2018-05-15 17:36:45 +00:00
}
html += ">" + this . name ;
if ( removeIcon ) {
2018-06-10 14:55:15 +01:00
html += "<i class='material-icons remove-icon op-icon'>delete</i>" ;
2018-05-15 17:36:45 +00:00
}
html += "</li>" ;
return html ;
}
/ * *
* Renders the operation in HTML as a full operation with ingredients .
*
* @ returns { string }
* /
toFullHtml ( ) {
2021-02-10 13:13:19 +00:00
let html = ` <div class="op-title"> ${ Utils . escapeHtml ( this . name ) } </div>
2018-06-19 00:55:08 +01:00
< div class = "ingredients" > ` ;
2018-05-15 17:36:45 +00:00
for ( let i = 0 ; i < this . ingList . length ; i ++ ) {
html += this . ingList [ i ] . toHtml ( ) ;
}
2018-06-19 00:55:08 +01:00
html += ` </div>
< div class = "recip-icons" >
2023-03-17 17:46:13 +00:00
< i class = "material-icons breakpoint" title = "Set breakpoint" break = "false" data - help - title = "Setting breakpoints" data - help = "Setting a breakpoint on an operation will cause execution of the Recipe to pause when it reaches that operation." > pause < / i >
< i class = "material-icons disable-icon" title = "Disable operation" disabled = "false" data - help - title = "Disabling operations" data - help = "Disabling an operation will prevent it from being executed when the Recipe is baked. Execution will skip over the disabled operation and continue with subsequent operations." > not _interested < / i >
2024-04-05 13:23:28 +02:00
< i class = "material-icons hide-args-icon" title = "Hide operation's arguments" hide - args = "false" data - help - title = "Hide operation's arguments" data - help = "Hiding an operation's argument will save space in the Recipe window. Execution will still take place with the selected argument options." > keyboard _arrow _up < / i >
2018-06-09 10:43:36 +01:00
< / d i v >
< div class = "clearfix" > & nbsp ; < / d i v > ` ;
2018-05-15 17:36:45 +00:00
return html ;
}
/ * *
2021-02-05 17:54:57 +00:00
* Highlights searched strings in the name and description of the operation .
2018-05-15 17:36:45 +00:00
*
2021-02-05 17:54:57 +00:00
* @ param { [ [ number ] ] } nameIdxs - Indexes of the search strings in the operation name [ [ start , length ] ]
* @ param { [ [ number ] ] } descIdxs - Indexes of the search strings in the operation description [ [ start , length ] ]
2018-05-15 17:36:45 +00:00
* /
2021-02-05 17:54:57 +00:00
highlightSearchStrings ( nameIdxs , descIdxs ) {
2021-02-09 11:50:20 +00:00
if ( nameIdxs . length && typeof nameIdxs [ 0 ] [ 0 ] === "number" ) {
2021-02-05 17:54:57 +00:00
let opName = "" ,
pos = 0 ;
nameIdxs . forEach ( idxs => {
const [ start , length ] = idxs ;
2021-02-09 11:50:20 +00:00
if ( typeof start !== "number" ) return ;
2021-02-05 17:54:57 +00:00
opName += this . name . slice ( pos , start ) + "<b>" +
this . name . slice ( start , start + length ) + "</b>" ;
pos = start + length ;
} ) ;
opName += this . name . slice ( pos , this . name . length ) ;
this . name = opName ;
2018-05-15 17:36:45 +00:00
}
2021-02-09 11:37:25 +00:00
if ( this . description && descIdxs . length && descIdxs [ 0 ] [ 0 ] >= 0 ) {
2018-05-15 17:36:45 +00:00
// Find HTML tag offsets
const re = /<[^>]+>/g ;
let match ;
while ( ( match = re . exec ( this . description ) ) ) {
// If the search string occurs within an HTML tag, return without highlighting it.
2021-02-05 17:54:57 +00:00
const inHTMLTag = descIdxs . reduce ( ( acc , idxs ) => {
const start = idxs [ 0 ] ;
return start >= match . index && start <= ( match . index + match [ 0 ] . length ) ;
} , false ) ;
if ( inHTMLTag ) return ;
2018-05-15 17:36:45 +00:00
}
2021-02-05 17:54:57 +00:00
let desc = "" ,
pos = 0 ;
descIdxs . forEach ( idxs => {
const [ start , length ] = idxs ;
desc += this . description . slice ( pos , start ) + "<b><u>" +
this . description . slice ( start , start + length ) + "</u></b>" ;
pos = start + length ;
} ) ;
desc += this . description . slice ( pos , this . description . length ) ;
this . description = desc ;
2018-05-15 17:36:45 +00:00
}
}
}
2018-08-21 19:07:13 +01:00
/ * *
* Given a URL for a Wikipedia ( or other wiki ) page , this function returns a link to that page .
*
2021-02-10 17:41:39 +00:00
* @ param { string } urlStr
2018-08-21 19:07:13 +01:00
* @ returns { string }
* /
2021-02-10 17:41:39 +00:00
function titleFromWikiLink ( urlStr ) {
const urlObj = url . parse ( urlStr ) ;
let wikiName = "" ,
pageTitle = "" ;
switch ( urlObj . host ) {
2024-02-03 02:02:13 +00:00
case "forensics.wiki" :
2021-02-10 17:41:39 +00:00
wikiName = "Forensics Wiki" ;
2024-02-03 02:02:13 +00:00
pageTitle = Utils . toTitleCase ( urlObj . path . replace ( /\//g , "" ) . replace ( /_/g , " " ) ) ;
2021-02-10 17:41:39 +00:00
break ;
case "wikipedia.org" :
wikiName = "Wikipedia" ;
pageTitle = urlObj . pathname . substr ( 6 ) . replace ( /_/g , " " ) ; // Chop off '/wiki/'
break ;
default :
// Not a wiki link, return full URL
return ` <a href=' ${ urlStr } ' target='_blank'>More Information<i class='material-icons inline-icon'>open_in_new</i></a> ` ;
2018-08-21 19:07:13 +01:00
}
2021-02-10 17:41:39 +00:00
return ` <a href=' ${ urlObj . href } ' target='_blank'> ${ pageTitle } <i class='material-icons inline-icon'>open_in_new</i></a> on ${ wikiName } ` ;
2018-08-21 19:07:13 +01:00
}
2018-05-15 17:36:45 +00:00
export default HTMLOperation ;