Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🚧 WIP Integrate parcel and refactor to more pure Vue components #459

Draft
wants to merge 39 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
ae69a91
Add parcel dependencies and run tasks
jaywon Mar 17, 2019
ed7270d
Convert custom environment parsing syntax for Post HTML syntax for va…
jaywon Mar 17, 2019
171e11f
Add parcel specific files/directories to .gitignore
jaywon Mar 17, 2019
c5174b1
Add .env example file to repo for self-documenting vars
jaywon Mar 17, 2019
b8e81e8
Merge branch 'develop' into chore/integrate-parcel
jaywon Mar 17, 2019
c1a52c0
:pencil2: Add .vscode directory to .gitignore
jaywon Mar 18, 2019
66d434b
:recycle: Create shared module for Vue EventBus singleton
jaywon Mar 18, 2019
e2ccd3c
Add global SCSS for starting to theme the application
jaywon Mar 18, 2019
c2d828f
:recycle: Refactor panel files into standard Vue Single File Component
jaywon Mar 18, 2019
3bff06d
:recycle: Refactor management pane to Vue Single File Component
jaywon Mar 18, 2019
a595939
:wrench: Add parcel build/run statements to watch entrypoints directory
jaywon Mar 18, 2019
3c72d1d
:heavy_plus_sign: Add Display components for migration/refactor
jaywon Mar 18, 2019
034d987
:fire: Delete display.css, migrated to Vue Display component
jaywon Mar 18, 2019
4394ae1
:recycle: Break out HudButton and HudButtons to their own components
jaywon Mar 20, 2019
7d4c1a8
:recycle: Break out Tab and Tabs to their own components
jaywon Mar 20, 2019
6ed9e7a
:recycle: Break out AlertAccordion to its own component
jaywon Mar 20, 2019
10b9211
:recycle: Refactor all modals into their own components
jaywon Mar 20, 2019
1ba51e7
:recycle: Break out ToolListItem to its own component
jaywon Mar 20, 2019
c99dd70
:recycle: Break out SiteTreeNode to its own component
jaywon Mar 20, 2019
5f1e77a
Uncomment Spectre css include for now, will evaluate spectre componen…
jaywon Mar 20, 2019
bb29d06
:recycle: Refactor display.html|css|js to a Vue Single Page Component…
jaywon Mar 20, 2019
f71b2be
:recycle: Refactor management.html|css|js to a Vue Single Page Compon…
jaywon Mar 20, 2019
8494797
:recycle: Stub out Drawer Single Page Component files for conversion
jaywon Mar 20, 2019
8b5ffe8
:fire: Remove manual vue dependencies in favor of parcel build from n…
jaywon Mar 20, 2019
641de54
:heavy_plus_sign: Add localforage import
jaywon Mar 20, 2019
165abc6
:recycle: Remove localforage script tag and clean up cruft
jaywon Mar 20, 2019
d8dcca3
Add TODO note for refactor
jaywon Mar 20, 2019
bcde54e
:recycle: Remove localforage script include and use ES6 import
jaywon Mar 20, 2019
440ea17
Add i18n compiled file to development environment since it's needed f…
jaywon Mar 22, 2019
098534d
:wrench: Change PostHTML delimiters to not conflict with Vue template…
jaywon Mar 22, 2019
74ee6d7
Refactor i18n interpolation and PostHTML delimiter syntax
jaywon Mar 22, 2019
7b8308d
:fire: Remove webpack dependencies and configuration
jaywon Mar 25, 2019
e9e34a1
:fire: Remove localforage downloaded copy for npm version
jaywon Mar 25, 2019
622c5da
:recycle: Convert display into entrypoint and associated files for ne…
jaywon Mar 25, 2019
47a4cad
:sparkles: Linter reformatting and minor cleanup
jaywon Mar 25, 2019
bbf848a
Add placeholder main file to start holding global styles
jaywon Mar 25, 2019
d795df9
:recycle: Conversion of all drawer related component
jaywon Mar 25, 2019
3dac5ee
:pencil2: Fix default locale in i18n init
jaywon Mar 25, 2019
1a327d3
:heavy_plus_sign: :heavy_minus_sign} Update node packages
jaywon Mar 27, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ZAP_HUD_FILES=https://zap
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

walking through the commits rn. haha. so this is where you set the variables to be pulled in by postHTML?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup! This file is just a template, for actual dev you would:

cp .env.example .env

And then edit for your environment. .env is in the .gitignore as often times this has values you don't want committed to repo. I added some copy in the README about it and @melsoriano will document in the wiki too.

ZAP_HUD_URL=https://targetdomain.com
ZAP_HUD_API=https://zap/api
ZAP_HUD_WS=https://zap/websocket
ZAP_HUD_TOOLS=http://zap/to/some/tool
ZAP_SHARED_SECRET=sometestsecret
ZAP_LOCALE=en_GB
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,8 @@
# JS
node_modules/
dist/
.cache
.env

# Visual Studio Code
.vscode
5,155 changes: 3,774 additions & 1,381 deletions package-lock.json

Large diffs are not rendered by default.

19 changes: 10 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
},
"scripts": {
"test": "ava",
"build": "webpack --config src/webpack/config.dev.js",
"dev": "parcel src/main/ZapHomeFiles/hud/entrypoints/**/*.html",
"build": "parcel build src/main/ZapHomeFiles/hud/entrypoints/**/*.html",
"lint": "xo",
"lint-staged": "lint-staged"
},
Expand Down Expand Up @@ -40,19 +41,19 @@
},
"homepage": "https://github.com/zaproxy/zap-hud/wiki",
"dependencies": {
"alertify": "^0.3.0",
"localforage": "^1.5.0",
"vue": "^2.6.9",
"vue": "^2.6.10",
"vue-i18n": "^8.9.0"
},
"devDependencies": {
"ava": "^1.3.1",
"css-loader": "^2.1.1",
"@vue/component-compiler-utils": "^2.6.0",
"ava": "^1.4.0",
"lint-staged": "^8.1.5",
"vue-loader": "^15.7.0",
"vue-style-loader": "^4.1.2",
"vue-template-compiler": "^2.6.9",
"webpack": "^4.29.6",
"webpack-cli": "^3.2.3",
"parcel-bundler": "^1.12.2",
"posthtml-expressions": "^1.1.0",
"sass": "^1.17.3",
"vue-template-compiler": "^2.6.10",
"xo": "^0.24.0"
}
}
48 changes: 48 additions & 0 deletions src/main/zapHomeFiles/hud/components/AlertAccordion.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<template>
<div class="accordion">
<input type="checkbox" :id="title" name="accordion-checkbox" hidden>
<label class="accordion-header" :for="title">{{ title }} {{ urlCount }}</label>
<div class="accordion-body">
<ul class="menu menu-nav">
<li class="menu-item" v-for="alert in alerts">
<!-- TODO: This should be alert.url but build was failing? -->
<a @click="alertSelect(alert)">{{ url }}</a>
</li>
</ul>
</div>
</div>
</template>

<script>
export default {
// template: "#alert-accordion-template",
props: ["title", "alerts", "port", "key"],
// props: {
// title: String,
// alerts: Array,
// port: Number,
// key: String
// },
methods: {
close: function() {
this.$emit("close");
},
urlCount: function() {
return this.alerts.length;
},
alertSelect: function(alert) {
// set keepShowing so that we don't hide the display frame
//TODO: replace app (Vue context w/ props)
app.keepShowing = true;
app.isAlertListModalShown = false;
app.isAllAlertsModalShown = false;

this.port.postMessage({ action: "alertSelected", alertId: alert.id });
}
}
};
</script>

<style lang="scss" scoped>
</style>

120 changes: 120 additions & 0 deletions src/main/zapHomeFiles/hud/components/AlertDetailsModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<template id="alert-details-modal-template">
<NavModal :title="title" :show="show" @close="close" @back="back">
<div slot="body">
<table class="table table-striped table-hover">
<tbody>
<tr>
<td v-t="'message.alerts_field_url'"></td>
<td @click="messageSelected(details.messageId)">
<a href="#">{{ details['url'] }}</a>
</td>
</tr>
<tr>
<td v-t="'message.alerts_field_description'"></td>
<td>{{ details['description'] }}</td>
</tr>
<tr>
<td v-t="'message.alerts_field_risk'"></td>
<td>{{ details['risk'] }}</td>
</tr>
<tr>
<td v-t="'message.alerts_field_confidence'"></td>
<td>{{ details['confidence'] }}</td>
</tr>
<tr>
<td v-t="'message.alerts_field_parameter'"></td>
<td>{{ details['parameter'] }}</td>
</tr>
<tr>
<td v-t="'message.alerts_field_attack'"></td>
<td>{{ details['attack'] }}</td>
</tr>
<tr>
<td v-t="'message.alerts_field_evidence'"></td>
<td>{{ details['evidence'] }}</td>
</tr>
<tr>
<td v-t="'message.alerts_field_cweid'"></td>
<td>{{ details['cweid'] }}</td>
</tr>
<tr>
<td v-t="'message.alerts_field_wascid'"></td>
<td>{{ details['wascid'] }}</td>
</tr>
<tr>
<td v-t="'message.alerts_field_other'"></td>
<td>{{ details['other'] }}</td>
</tr>
<tr>
<td v-t="'message.alerts_field_solution'"></td>
<td>{{ details['solution'] }}</td>
</tr>
<tr>
<td v-t="'message.alerts_field_reference'"></td>
<td v-if="details['reference']">
<li v-for="link in details['reference'].split('\n')">
<a :href="link" target="_top">{{ link }}</a>
</li>
</td>
<td v-else></td>
</tr>
</tbody>
</table>
</div>
</NavModal>
</template>

<script>
import { EventBus } from "../libs/event-bus.js";
import NavModal from "./NavModal.vue";

export default {
template: "#alert-details-modal-template",
props: ["show", "title"],
components: {
NavModal
},
methods: {
close: function() {
this.$emit("close");
},
messageSelected: function(id) {
//TODO: replace tabId, frameId w/ props
navigator.serviceWorker.controller.postMessage({
tabId: tabId,
frameId: frameId,
action: "showHttpMessageDetails",
tool: "history",
id: id
});
},
back: function() {
//TODO: replace app (Vue context w/ props)
app.keepShowing = true;
app.isAlertDetailsModalShown = false;
this.port.postMessage({ back: true });
}
},
data() {
return {
port: null,
details: {}
};
},
created() {
let self = this;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't tried building the code from your PR yet, but I wonder a little why the clone of 'this'. Shouldn't the fat arrow function of the EventBus pass the scope natively? And even if this is merely an assignment instead of a deep copy, it does cost some cycles. Considering that this is all being run simultaneously in one browser window I would look for all opportunities to shave performance hits.

EventBus.$on("showAlertDetailsModal", data => {
//TODO: replace app (Vue context w/ props)
app.isAlertDetailsModalShown = true;
app.alertDetailsModalTitle = data.title;

self.details = data.details;
self.port = data.port;
});
}
};
</script>

<style lang="scss" scoped>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Every block you aren't using costs time in the development IDE (especially scoped style blocks). I have to recommend removing EVERYTHING that is not needed. End users won't thank you for it, but devs certainly will.

</style>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a new-line at eof?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jsoref Can you clarify the need or value add of adding a new-line? I'm just curious if that's compliance w/ a tool or some other purpose.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

git diff (and every other diff) get really pissy about this.

Basically all tools that work on whole lines (newline terminated) make optimizations based on this. So, whenever it's violated, they have to do a lot of work to undo this assumption.

And standard text editors (e.g. vi) will by default insert the newline. This means that if I (or someone else) use such an editor to make a change to a file which is missing the newline, the editor will add it, and git (or hg or ...) will blame us for changing that last line -- even if our change is in fact nowhere near. Once our change is merged, anyone who uses a blame tool will see us as having made the change to that last line, and if further lines are added below, it'll look like we changed that specific line.

So, as a general rule, the best policy is to always include the newline.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gotcha, thanks for the clarification. Seems like something a linter should be responsible for enforcing ultimately.

54 changes: 54 additions & 0 deletions src/main/zapHomeFiles/hud/components/AlertListModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<!-- alert list modal component -->
<template>
<Modal :title="title" :show="show" @close="close">
<div slot="body">
<AlertAccordion
v-for="(value, key) in alerts"
:key="key"
:title="key"
:alerts="value"
:port="port"
@close="close"
@open="open"
></AlertAccordion>
</div>
</Modal>
</template>

<script>
import { EventBus } from "../libs/event-bus.js";
import Modal from "./Modal.vue";
import AlertAccordion from "./AlertAccordion.vue";

export default {
// template: "#alert-list-modal-template",
props: ["show", "title"],
components: {
Modal,
AlertAccordion
},
methods: {
close: function() {
this.$emit("close");
}
},
data() {
return {
port: null,
alerts: {}
};
},
created() {
let self = this;

EventBus.$on("showAlertListModal", data => {
//TODO: replace app (Vue context w/ props)
app.isAlertListModalShown = true;
app.alertListModalTitle = data.title;

self.alerts = data.alerts;
self.port = data.port;
});
}
};
</script>
100 changes: 100 additions & 0 deletions src/main/zapHomeFiles/hud/components/AllAlertsModal.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<template>
<Modal :title="title" :show="show" @close="close">
<div slot="body">
<Tabs :activetab="activeTab">
<Tab :name="$t('message.alerts_risk_high')" :selected="true">
<AlertAccordion
v-for="(value, key) in alerts['High']"
:key="key"
:title="key"
:alerts="value"
:port="port"
@close="close"
></AlertAccordion>
</Tab>

<Tab :name="$t('message.alerts_risk_medium')">
<AlertAccordion
v-for="(value, key) in alerts['Medium']"
:key="key"
:title="key"
:alerts="value"
:port="port"
@close="close"
></AlertAccordion>
</Tab>

<Tab :name="$t('message.alerts_risk_low')">
<AlertAccordion
v-for="(value, key) in alerts['Low']"
:key="key"
:title="key"
:alerts="value"
:port="port"
@close="close"
></AlertAccordion>
</Tab>

<Tab :name="$t('message.alerts_risk_info')">
<AlertAccordion
v-for="(value, key) in alerts['Informational']"
:key="key"
:title="key"
:alerts="value"
:port="port"
@close="close"
></AlertAccordion>
</Tab>
</Tabs>
</div>
</Modal>
</template>

<script>
import { EventBus } from "../libs/event-bus.js";
import VueI18n from "vue-i18n";
import Modal from "./Modal.vue";
import Tabs from "./Tabs.vue";
import Tab from "./Tab.vue";
import AlertAccordion from "./AlertAccordion.vue";

export default {
// template: "#all-alerts-modal-template",
props: ["show", "title"],
components: {
AlertAccordion,
Tabs,
Tab
},
methods: {
close: function() {
this.$emit("close");
}
},
data() {
return {
port: null,
alerts: {},
activeTab: I18n.t("alerts_risk_high")
};
},
created: function() {
let self = this;

EventBus.$on("showAllAlertsModal", data => {
//TODO: replace app (Vue context w/ props)
app.isAllAlertsModalShown = true;
app.allAlertsModalTitle = data.title;

self.alerts = data.alerts;
self.port = data.port;
self.activeTab = data.risk;
});
}
};
</script>

<style lang="scss" scoped>
</style>


Loading