This commit is contained in:
Liyas Thomas
2019-10-29 12:18:01 +05:30
14 changed files with 661 additions and 483 deletions

View File

@@ -38,11 +38,12 @@
</ul>
</div>
</pw-modal>
<pw-section class="blue" icon="cloud_upload" label="Request" ref="request">
<ul>
<li>
<label for="method">Method</label>
<select id="method" v-model="method">
<select id="method" v-model="method" @change="methodChange">
<option>GET</option>
<option>HEAD</option>
<option>POST</option>
@@ -129,20 +130,22 @@
</ul>
<ul v-for="(param, index) in bodyParams" :key="index">
<li>
<input
:placeholder="'key '+(index+1)"
:name="'bparam'+index"
v-model="param.key"
@keyup.prevent="setRouteQueryState"
<input
:placeholder="'key '+(index+1)"
:name="'bparam'+index"
:value="param.key"
@change="$store.commit('setKeyBodyParams', { index, value: $event.target.value })"
@keyup.prevent="setRouteQueryState"
autofocus
/>
</li>
<li>
<input
:placeholder="'value '+(index+1)"
:id="'bvalue'+index"
:name="'bvalue'+index"
v-model="param.value"
<input
:placeholder="'value '+(index+1)"
:id="'bvalue'+index"
:name="'bvalue'+index"
:value="param.value"
@change="$store.commit('setValueBodyParams', { index, value: $event.target.value })"
@keyup.prevent="setRouteQueryState"
/>
</li>
@@ -206,9 +209,9 @@
id="copyRequest"
ref="copyRequest"
:disabled="!isValidURL"
v-tooltip.bottom="'Sharable request URL'"
v-tooltip.bottom="'Copy Request URL'"
>
<i class="material-icons">share</i>
<i class="material-icons">file_copy</i>
</button>
<button
class="icon"
@@ -220,7 +223,7 @@
>
<i class="material-icons">save</i>
</button>
<button class="icon" @click="clearContent" v-tooltip.bottom="'Clear all'">
<button class="icon" @click="clearContent" v-tooltip.bottom="'Clear All'">
<i class="material-icons">clear_all</i>
</button>
</div>
@@ -263,62 +266,7 @@
</li>
</ul>
</pw-section>
<pw-section class="purple" icon="cloud_download" id="response" label="Response" ref="response">
<ul>
<li>
<label for="status">status</label>
<input
:class="statusCategory ? statusCategory.className : ''"
:value="response.status || '(waiting to send request)'"
ref="status"
id="status"
name="status"
readonly
type="text"
/>
</li>
</ul>
<ul v-for="(value, key) in response.headers" :key="key">
<li>
<label :for="key">{{key}}</label>
<input :id="key" :value="value" :name="key" readonly />
</li>
</ul>
<ul v-if="response.body">
<li>
<div class="flex-wrap">
<label for="body">response</label>
<div>
<button class="icon" @click="copyResponse" ref="copyResponse" v-if="response.body">
<i class="material-icons">file_copy</i>
<span>Copy</span>
</button>
</div>
</div>
<div id="response-details-wrapper">
<pre><code
ref="responseBody"
id="body"
rows="16"
placeholder="(waiting to send request)"
>{{response.body}}</code></pre>
<iframe
:class="{hidden: !previewEnabled}"
class="covers-response"
ref="previewFrame"
src="about:blank"
></iframe>
</div>
<div class="align-right" v-if="response.body && responseType === 'text/html'">
<button class="icon" @click.prevent="togglePreview">
<i class="material-icons" v-if="!previewEnabled">visibility</i>
<i class="material-icons" v-if="previewEnabled">visibility_off</i>
<span>{{ previewEnabled ? 'Hide Preview' : 'Preview HTML' }}</span>
</button>
</div>
</li>
</ul>
</pw-section>
<section>
<input id="tab-one" type="radio" name="grp" checked="checked" />
<label for="tab-one">Authentication</label>
@@ -373,6 +321,13 @@
<input placeholder="Token" name="bearer_token" v-model="bearerToken" />
</li>
</ul>
<div class="flex-wrap">
<pw-toggle
:on="!urlExcludes.auth"
@change="setExclude('auth', !$event)">
Include in URL
</pw-toggle>
</div>
</pw-section>
</div>
<input id="tab-two" type="radio" name="grp" />
@@ -402,19 +357,21 @@
</ul>
<ul v-for="(header, index) in headers" :key="index">
<li>
<input
:placeholder="'header '+(index+1)"
:name="'header'+index"
v-model="header.key"
@keyup.prevent="setRouteQueryState"
<input
:placeholder="'header '+(index+1)"
:name="'header'+index"
:value="header.key"
@change="$store.commit('setKeyHeader', { index, value: $event.target.value })"
@keyup.prevent="setRouteQueryState"
autofocus
/>
</li>
<li>
<input
:placeholder="'value '+(index+1)"
:name="'value'+index"
v-model="header.value"
<input
:placeholder="'value '+(index+1)"
:name="'value'+index"
:value="header.value"
@change="$store.commit('setValueHeader', { index, value: $event.target.value })"
@keyup.prevent="setRouteQueryState"
/>
</li>
@@ -463,15 +420,21 @@
</ul>
<ul v-for="(param, index) in params" :key="index">
<li>
<input
:placeholder="'parameter '+(index+1)"
:name="'param'+index"
v-model="param.key"
<input
:placeholder="'parameter '+(index+1)"
:name="'param'+index"
:value="param.key"
@change="$store.commit('setKeyParams', { index, value: $event.target.value })"
autofocus
/>
</li>
<li>
<input :placeholder="'value '+(index+1)" :name="'value'+index" v-model="param.value" />
<input
:placeholder="'value '+(index+1)"
:name="'value'+index"
:value="param.value"
@change="$store.commit('setValueParams', { index, value: $event.target.value })"
/>
</li>
<div>
<li>
@@ -492,10 +455,75 @@
</pw-section>
</div>
</section>
<history @useHistory="handleUseHistory" ref="historyComponent"></history>
<pw-section class="yellow" icon="folder_special" label="Collections" ref="Collections">
<collections></collections>
<br>
<pw-section class="purple" icon="cloud_download" id="response" label="Response" ref="response">
<ul>
<li>
<label for="status">status</label>
<input
:class="statusCategory ? statusCategory.className : ''"
:value="response.status || '(waiting to send request)'"
ref="status"
id="status"
name="status"
readonly
type="text"
/>
</li>
</ul>
<ul v-for="(value, key) in response.headers" :key="key">
<li>
<label :for="key">{{key}}</label>
<input :id="key" :value="value" :name="key" readonly />
</li>
</ul>
<ul v-if="response.body">
<li>
<div class="flex-wrap">
<label for="body">response</label>
<div>
<button class="icon" @click="copyResponse" ref="copyResponse" v-if="response.body">
<i class="material-icons">file_copy</i>
<span>Copy</span>
</button>
</div>
</div>
<div id="response-details-wrapper">
<pre><code
ref="responseBody"
id="body"
rows="16"
placeholder="(waiting to send request)"
>{{response.body}}</code></pre>
<iframe
:class="{hidden: !previewEnabled}"
class="covers-response"
ref="previewFrame"
src="about:blank"
></iframe>
</div>
<div class="align-right" v-if="response.body && responseType === 'text/html'">
<button class="icon" @click.prevent="togglePreview">
<i class="material-icons" v-if="!previewEnabled">visibility</i>
<i class="material-icons" v-if="previewEnabled">visibility_off</i>
<span>{{ previewEnabled ? 'Hide Preview' : 'Preview HTML' }}</span>
</button>
</div>
</li>
</ul>
</pw-section>
<br>
<pw-section class="yellow" icon="folder_special" label="Collections" ref="Collections">
<collections />
</pw-section>
<br>
<history @useHistory="handleUseHistory" ref="historyComponent"></history>
</div>
</template>
<script>
@@ -577,27 +605,11 @@ export default {
collections,
saveRequestAs
},
data() {
data () {
return {
label: "",
showModal: false,
copyButton: '<i class="material-icons">file_copy</i>',
copiedButton: '<i class="material-icons">done</i>',
method: "GET",
url: "https://reqres.in",
auth: "None",
path: "/api/users",
httpUser: "",
httpPassword: "",
passwordFieldType: "password",
bearerToken: "",
headers: [],
params: [],
bodyParams: [],
rawParams: "",
rawInput: false,
contentType: "application/json",
requestType: "JavaScript XHR",
isHidden: true,
response: {
status: "",
@@ -628,10 +640,18 @@ export default {
"text/plain"
],
showRequestModal: false,
editRequest: {}
editRequest: {},
urlExcludes: {}
};
},
watch: {
urlExcludes: {
deep: true,
handler () {
this.$store.commit("postwoman/applySetting", ['URL_EXCLUDES', Object.assign({}, this.urlExcludes)]);
}
},
contentType(val) {
this.rawInput = !this.knownContentTypes.includes(val);
},
@@ -718,6 +738,71 @@ export default {
}
},
computed: {
url: {
get() { return this.$store.state.request.url; },
set(value) { this.$store.commit('setState', { value, 'attribute': 'url' }) },
},
method: {
get() { return this.$store.state.request.method; },
set(value) { this.$store.commit('setState', { value, 'attribute': 'method' }) },
},
path: {
get() { return this.$store.state.request.path; },
set(value) { this.$store.commit('setState', { value, 'attribute': 'path' }) },
},
label: {
get() { return this.$store.state.request.label; },
set(value) { this.$store.commit('setState', { value, 'attribute': 'label' }) },
},
auth: {
get() { return this.$store.state.request.auth; },
set(value) { this.$store.commit('setState', { value, 'attribute': 'auth' }) },
},
httpUser: {
get() { return this.$store.state.request.httpUser; },
set(value) { this.$store.commit('setState', { value, 'attribute': 'httpUser' }) },
},
httpPassword: {
get() { return this.$store.state.request.httpPassword; },
set(value) { this.$store.commit('setState', { value, 'attribute': 'httpPassword' }) },
},
bearerToken: {
get() { return this.$store.state.request.bearerToken; },
set(value) { this.$store.commit('setState', { value, 'attribute': 'bearerToken' }) },
},
headers: {
get() { return this.$store.state.request.headers; },
set(value) { this.$store.commit('setState', { value, 'attribute': 'headers' }) },
},
params: {
get() { return this.$store.state.request.params; },
set(value) { this.$store.commit('setState', { value, 'attribute': 'params' }) },
},
bodyParams: {
get() { return this.$store.state.request.bodyParams; },
set(value) { this.$store.commit('setState', { value, 'attribute': 'bodyParams' }) },
},
rawParams: {
get() { return this.$store.state.request.rawParams; },
set(value) { this.$store.commit('setState', { value, 'attribute': 'rawParams' }) },
},
rawInput: {
get() { return this.$store.state.request.rawInput; },
set(value) { this.$store.commit('setState', { value, 'attribute': 'rawInput' }) },
},
requestType: {
get() { return this.$store.state.request.requestType; },
set(value) { this.$store.commit('setState', { value, 'attribute': 'requestType' }) },
},
contentType: {
get() { return this.$store.state.request.contentType; },
set(value) { this.$store.commit('setState', { value, 'attribute': 'contentType' }) },
},
passwordFieldType: {
get() { return this.$store.state.request.passwordFieldType; },
set(value) { this.$store.commit('setState', { value, 'attribute': 'passwordFieldType' }) }
},
selectedRequest() {
return this.$store.state.postwoman.selectedRequest;
},
@@ -851,31 +936,21 @@ export default {
requestString.push(' method: "' + this.method + '",\n');
if (this.auth === "Basic") {
var basic = this.httpUser + ":" + this.httpPassword;
headers.push(
' "Authorization": "Basic ' +
window.btoa(unescape(encodeURIComponent(basic))) +
",\n"
);
this.$store.commit('addHeaders', ' "Authorization": "Basic ' + window.btoa(unescape(encodeURIComponent(basic))) + ",\n")
} else if (this.auth === "Bearer Token") {
headers.push(
' "Authorization": "Bearer Token ' + this.bearerToken + ",\n"
);
this.$store.commit('addHeaders', ' "Authorization": "Bearer Token ' + this.bearerToken + ",\n")
}
if (["POST", "PUT", "PATCH"].includes(this.method)) {
const requestBody = this.rawInput
? this.rawParams
: this.rawRequestBody;
requestString.push(" body: " + requestBody + ",\n");
headers.push(' "Content-Length": ' + requestBody.length + ",\n");
headers.push(
' "Content-Type": "' + this.contentType + '; charset=utf-8",\n'
);
this.$store.commit('addHeaders', ' "Content-Length": ' + requestBody.length + ",\n")
this.$store.commit('addHeaders', ' "Content-Type": "' + this.contentType + '; charset=utf-8",\n')
}
if (this.headers) {
this.headers.forEach(function(element) {
headers.push(
' "' + element.key + '": "' + element.value + '",\n'
);
this.$store.commit('addHeaders', ' "' + element.key + '": "' + element.value + '",\n')
});
}
headers = headers.join("").slice(0, -3);
@@ -954,7 +1029,7 @@ export default {
const config = this.$store.state.postwoman.settings.PROXY_ENABLED
? {
method: "POST",
url: `${window.location.protocol}//${window.location.host}/proxy`,
url: `https://postwoman.apollotv.xyz/`,
data: requestOptions
}
: requestOptions;
@@ -1128,40 +1203,34 @@ export default {
this.params = params;
},
addRequestHeader() {
this.headers.push({
this.$store.commit('addHeaders', {
key: "",
value: ""
});
return false;
},
removeRequestHeader(index) {
this.headers.splice(index, 1);
this.$store.commit('removeHeaders', index)
this.$toast.error("Deleted", {
icon: "delete"
});
},
addRequestParam() {
this.params.push({
key: "",
value: ""
});
this.$store.commit('addParams', { key: "", value: "" })
return false;
},
removeRequestParam(index) {
this.params.splice(index, 1);
this.$store.commit('removeParams', index)
this.$toast.error("Deleted", {
icon: "delete"
});
},
addRequestBodyParam() {
this.bodyParams.push({
key: "",
value: ""
});
this.$store.commit('addBodyParams', { key: "", value: "" })
return false;
},
removeRequestBodyParam(index) {
this.bodyParams.splice(index, 1);
this.$store.commit('removeBodyParams', index)
this.$toast.error("Deleted", {
icon: "delete"
});
@@ -1218,13 +1287,13 @@ export default {
document.execCommand("copy");
document.body.removeChild(dummy);
this.$refs.copyRequest.innerHTML = this.copiedButton;
this.$toast.success("Copied to clipboard", {
this.$toast.info("Copied to clipboard", {
icon: "done"
});
setTimeout(
() =>
(this.$refs.copyRequest.innerHTML =
'<i class="material-icons">share</i>'),
'<i class="material-icons">file_copy</i>'),
1000
);
}
@@ -1311,12 +1380,12 @@ export default {
"method",
"url",
"path",
"auth",
!this.urlExcludes.auth ? "auth" : null,
"httpUser",
"httpPassword",
"bearerToken",
"contentType"
].map(item => flat(item));
].filter((item) => item !== null).map(item => flat(item));
let deeps = ["headers", "params"].map(item => deep(item));
let bodyParams = this.rawInput
? [flat("rawParams")]
@@ -1373,10 +1442,7 @@ export default {
this.path = "";
this.headers = [];
for (const key of Object.keys(parsedCurl.headers)) {
this.headers.push({
key: key,
value: parsedCurl.headers[key]
});
this.$store.commit('addHeaders', { key: key, value: parsedCurl.headers[key] })
}
this.method = parsedCurl.method.toUpperCase();
if (parsedCurl["data"]) {
@@ -1463,12 +1529,25 @@ export default {
hideRequestModal() {
this.showRequestModal = false;
this.editRequest = {};
},
setExclude (excludedField, excluded) {
this.urlExcludes[excludedField] = excluded;
this.setRouteQueryState();
},
methodChange() {
// this.$store.commit('setState', { 'value': ["POST", "PUT", "PATCH"].includes(this.method) ? 'application/json' : '', 'attribute': 'contentType' })
this.contentType = ["POST", "PUT", "PATCH"].includes(this.method) ? 'application/json' : '';
}
},
mounted() {
this.observeRequestButton();
},
created() {
this.urlExcludes = this.$store.state.postwoman.settings.URL_EXCLUDES || {
// Exclude authentication by default for security reasons.
auth: true
};
if (Object.keys(this.$route.query).length)
this.setRouteQueries(this.$route.query);
this.$watch(
@@ -1493,4 +1572,4 @@ export default {
);
}
};
</script>
</script>

View File

@@ -40,9 +40,9 @@
<h3 class="title">Frames</h3>
<span>
<pw-toggle
:on="!settings.DISABLE_FRAME_COLORS"
@change="applySetting('DISABLE_FRAME_COLORS', $event)"
>Multi-color {{ settings.DISABLE_FRAME_COLORS ? "Disabled" : "Enabled" }}</pw-toggle>
:on="settings.FRAME_COLORS_ENABLED"
@change="toggleSetting('FRAME_COLORS_ENABLED')"
>Multi-color {{ settings.FRAME_COLORS_ENABLED ? "Enabled" : "Disabled" }}</pw-toggle>
</span>
</li>
</ul>
@@ -50,12 +50,17 @@
<pw-section class="blue" icon="public" label="Proxy">
<ul>
<li>
<pw-toggle
:on="settings.PROXY_ENABLED"
@change="applySetting('PROXY_ENABLED', $event)"
>Proxy {{ settings.PROXY_ENABLED ? "enabled" : "disabled" }}</pw-toggle>
<span>
<pw-toggle
:on="settings.PROXY_ENABLED"
@change="toggleSetting('PROXY_ENABLED')"
>Proxy {{ settings.PROXY_ENABLED ? "enabled" : "disabled" }}</pw-toggle>
</span>
</li>
</ul>
<ul class="info">
<li><p>Postwoman's Proxy is hosted by ApolloTV.<br>Read the ApolloTV privacy policy <a href="https://apollotv.xyz/legal" target="_blank">here</a>.</p></li>
</ul>
<!--
PROXY SETTINGS URL AND KEY
--------------
@@ -75,6 +80,13 @@
</div>
</template>
<style scoped>
.info {
margin-left: 4px;
color: var(--fg-light-color);
}
</style>
<script>
import section from "../components/section";
import swatch from "../components/settings/swatch";
@@ -167,8 +179,8 @@
THEME_TAB_COLOR: "",
THEME_COLOR_VIBRANT: true,
DISABLE_FRAME_COLORS:
this.$store.state.postwoman.settings.DISABLE_FRAME_COLORS || false,
FRAME_COLORS_ENABLED:
this.$store.state.postwoman.settings.FRAME_COLORS_ENABLED || false,
PROXY_ENABLED:
this.$store.state.postwoman.settings.PROXY_ENABLED || false,
PROXY_URL: this.$store.state.postwoman.settings.PROXY_URL || "",