Merge branch 'master' into feature/env-manager

This commit is contained in:
Jacob Anavisca
2020-02-23 11:39:44 -05:00
committed by GitHub
18 changed files with 465 additions and 126 deletions

View File

@@ -204,7 +204,7 @@ _**All `i18n` contributions are welcome to `i18n` [branch](https://github.com/li
- **[CLI β](https://github.com/postwoman-io/postwoman-cli)** - A CLI solution for Postwoman - **[CLI β](https://github.com/postwoman-io/postwoman-cli)** - A CLI solution for Postwoman
- **Browser Extensions** - Browser extensions that simplifies access to Postwoman - **Browser Extensions** - Browser extensions that simplifies access to Postwoman
[![Firefox](https://raw.github.com/alrra/browser-logos/master/src/firefox/firefox_16x16.png) **Firefox**](https://addons.mozilla.org/en-US/firefox/addon/postwoman) ([GitHub](https://github.com/AndrewBastin/postwoman-firefox))  |  [![Chrome](https://raw.github.com/alrra/browser-logos/master/src/chrome/chrome_16x16.png) **Chrome**](https://chrome.google.com/webstore/detail/postwoman-extension-for-c/amknoiejhlmhancpahfcfcfhllgkpbld) ([GitHub](https://github.com/AndrewBastin/postwoman-chrome)) [![Firefox](https://raw.github.com/alrra/browser-logos/master/src/firefox/firefox_16x16.png) **Firefox**](https://addons.mozilla.org/en-US/firefox/addon/postwoman)  |  [![Chrome](https://raw.github.com/alrra/browser-logos/master/src/chrome/chrome_16x16.png) **Chrome**](https://chrome.google.com/webstore/detail/postwoman-extension-for-c/amknoiejhlmhancpahfcfcfhllgkpbld) ([GitHub](https://github.com/AndrewBastin/postwoman-extension))
>**Extensions fixes `CORS` issues.** >**Extensions fixes `CORS` issues.**

View File

@@ -22,13 +22,11 @@ $responsiveWidth: 768px;
::-webkit-scrollbar { ::-webkit-scrollbar {
width: 4px; width: 4px;
height: 4px; height: 4px;
border-radius: 4px; background-color: var(--bg-dark-color);
background-color: var(--bg-light-color);
} }
::-webkit-scrollbar-thumb { ::-webkit-scrollbar-thumb {
background-color: var(--fg-light-color); background-color: var(--fg-light-color);
border-radius: 8px;
&:hover { &:hover {
background-color: var(--fg-color); background-color: var(--fg-color);
@@ -60,9 +58,9 @@ body {
padding: 0; padding: 0;
margin: 0; margin: 0;
scroll-behavior: smooth; scroll-behavior: smooth;
transition: all 0.2s ease-in-out;
} }
// Make theme transition smoother.
body.afterLoad { body.afterLoad {
transition: background-color 0.2s ease-in-out; transition: background-color 0.2s ease-in-out;
} }
@@ -76,6 +74,10 @@ a {
color: inherit; color: inherit;
text-decoration: none; text-decoration: none;
transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out;
&.link {
color: var(--ac-color);
}
} }
header, header,
@@ -146,7 +148,8 @@ footer {
z-index: 1; z-index: 1;
height: 100vh; height: 100vh;
padding: 0 8px; padding: 0 8px;
background-color: var(--bg-light-color); background-color: var(--bg-dark-color);
transition: all 0.2s ease-in-out;
} }
.main { .main {
@@ -173,6 +176,7 @@ nav.primary-nav {
svg { svg {
fill: var(--fg-light-color); fill: var(--fg-light-color);
transition: all 0.2s ease-in-out;
} }
a { a {
@@ -186,7 +190,6 @@ nav.primary-nav {
color: var(--fg-light-color); color: var(--fg-light-color);
fill: var(--fg-light-color); fill: var(--fg-light-color);
margin: 8px 0; margin: 8px 0;
transition: all 0.2s ease-in-out;
&:hover { &:hover {
color: var(--fg-color); color: var(--fg-color);
@@ -263,11 +266,16 @@ hr {
border-bottom: 1px dashed var(--brd-color); border-bottom: 1px dashed var(--brd-color);
} }
p {
transition: all 0.2s ease-in-out;
}
.tooltip { .tooltip {
$bgcolor: var(--tt-color); $bgcolor: var(--tt-color);
$fgcolor: var(--fg-color); $fgcolor: var(--fg-color);
display: block !important; display: block !important;
z-index: 10000; z-index: 10000;
transition: all 0.2s ease-in-out;
.tooltip-inner { .tooltip-inner {
background: $bgcolor; background: $bgcolor;
@@ -422,7 +430,6 @@ button {
color: var(--act-color); color: var(--act-color);
fill: var(--act-color); fill: var(--act-color);
box-shadow: inset 0 0 0 2px var(--fg-color); box-shadow: inset 0 0 0 2px var(--fg-color);
transition: all 0.2s ease-in-out;
} }
&.icon { &.icon {
@@ -437,7 +444,6 @@ button {
color: var(--fg-color); color: var(--fg-color);
fill: var(--fg-color); fill: var(--fg-color);
box-shadow: none; box-shadow: none;
transition: all 0.2s ease-in-out;
} }
} }
@@ -472,8 +478,19 @@ button {
fieldset { fieldset {
margin: 16px 0; margin: 16px 0;
border-radius: 16px; border-radius: 16px;
transition: all 0.2s ease-in-out;
background-color: var(--bg-dark-color); background-color: var(--bg-dark-color);
transition: all 0.2s ease-in-out;
}
fieldset:target,
section:target {
animation: highlight 2s ease;
}
@keyframes highlight {
50% {
box-shadow: 0 0 0 2px var(--ac-color);
}
} }
legend { legend {
@@ -483,6 +500,7 @@ legend {
color: var(--fg-color); color: var(--fg-color);
font-weight: 700; font-weight: 700;
cursor: pointer; cursor: pointer;
transition: all 0.2s ease-in-out;
* { * {
vertical-align: middle; vertical-align: middle;
@@ -565,7 +583,6 @@ code {
&:not([readonly]):not(.ace_editor):active, &:not([readonly]):not(.ace_editor):active,
&:not([readonly]):not(.ace_editor):focus { &:not([readonly]):not(.ace_editor):focus {
box-shadow: inset 0 0 0 2px var(--fg-light-color); box-shadow: inset 0 0 0 2px var(--fg-light-color);
transition: all 0.2s ease-in-out;
} }
} }
@@ -576,7 +593,6 @@ code {
&:active, &:active,
&:focus { &:focus {
box-shadow: inset 0 0 0 2px var(--fg-light-color); box-shadow: inset 0 0 0 2px var(--fg-light-color);
transition: all 0.2s ease-in-out;
} }
} }
@@ -681,6 +697,7 @@ input[type="checkbox"] {
label { label {
padding: 4px; padding: 4px;
color: var(--fg-light-color); color: var(--fg-light-color);
transition: all 0.2s ease-in-out;
} }
ul, ul,
@@ -805,6 +822,7 @@ ol li {
section { section {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
border-radius: 16px;
} }
.tab { .tab {
@@ -884,18 +902,19 @@ input[type="radio"]:checked + label + .tab {
padding: 0; padding: 0;
width: 100%; width: 100%;
background-color: var(--bg-color); background-color: var(--bg-color);
transition: all 0.2s ease-in-out;
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.45); box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.45);
} }
nav.primary-nav { nav.primary-nav {
flex-flow: row nowrap; flex-flow: row nowrap;
overflow: auto; overflow: auto;
justify-content: space-around; justify-content: space-between;
background-color: var(--bg-dark-color);
a { a {
background-color: transparent; background-color: transparent;
margin: 8px; margin: 8px;
flex: 1;
&.nuxt-link-exact-active { &.nuxt-link-exact-active {
background-color: transparent; background-color: transparent;

View File

@@ -120,20 +120,40 @@ export default {
reader.onload = event => { reader.onload = event => {
let content = event.target.result; let content = event.target.result;
let collections = JSON.parse(content); let collections = JSON.parse(content);
this.$store.commit("postwoman/replaceCollections", collections); if (collections[0]) {
let [ name, folders, requests ] = Object.keys(collections[0])
if (name === 'name' && folders === 'folders' && requests === 'requests') {
// Do nothing
}
} else if (collections.info && collections.info.schema.includes('v2.1.0')) {
collections = this.parsePostmanCollection(collections)
} else {
return this.failedImport();
}
this.$store.commit("postwoman/importCollections", collections);
this.fileImported();
}; };
reader.readAsText(this.$refs.inputChooseFileToReplaceWith.files[0]); reader.readAsText(this.$refs.inputChooseFileToReplaceWith.files[0]);
this.fileImported();
}, },
importFromJSON() { importFromJSON() {
let reader = new FileReader(); let reader = new FileReader();
reader.onload = event => { reader.onload = event => {
let content = event.target.result; let content = event.target.result;
let collections = JSON.parse(content); let collections = JSON.parse(content);
if (collections[0]) {
let [ name, folders, requests ] = Object.keys(collections[0])
if (name === 'name' && folders === 'folders' && requests === 'requests') {
// Do nothing
}
} else if (collections.info && collections.info.schema.includes('v2.1.0')) {
collections = this.parsePostmanCollection(collections);
} else {
return this.failedImport();
}
this.$store.commit("postwoman/importCollections", collections); this.$store.commit("postwoman/importCollections", collections);
this.fileImported();
}; };
reader.readAsText(this.$refs.inputChooseFileToImportFrom.files[0]); reader.readAsText(this.$refs.inputChooseFileToImportFrom.files[0]);
this.fileImported();
}, },
exportJSON() { exportJSON() {
let text = this.collectionJson; let text = this.collectionJson;
@@ -161,6 +181,114 @@ export default {
this.$toast.info(this.$t("file_imported"), { this.$toast.info(this.$t("file_imported"), {
icon: "folder_shared" icon: "folder_shared"
}); });
},
failedImport() {
this.$toast.error(this.$t("import_failed"), {
icon: "error"
});
},
parsePostmanCollection(collection, folders = true) {
let postwomanCollection = folders ? [{
"name": "",
"folders": [],
"requests": []
}]
: {
"name": "",
"requests": []
};
for(let collectionItem of collection.item) {
if (collectionItem.request) {
if (postwomanCollection[0]) {
postwomanCollection[0].name = collection.info ? collection.info.name : "";
postwomanCollection[0].requests.push(this.parsePostmanRequest(collectionItem));
} else {
postwomanCollection.name = collection.name ? collection.name
: "";
postwomanCollection.requests.push(this.parsePostmanRequest(collectionItem));
}
} else if (collectionItem.item) {
if (collectionItem.item[0]) {
postwomanCollection[0].folders.push(this.parsePostmanCollection(collectionItem, false));
}
}
}
return postwomanCollection;
},
parsePostmanRequest(requestObject) {
let pwRequest = {
"url": "",
"path": "",
"method": "",
"auth": "",
"httpUser": "",
"httpPassword": "",
"passwordFieldType": "password",
"bearerToken": "",
"headers": [],
"params": [],
"bodyParams": [],
"rawParams": "",
"rawInput": false,
"contentType": "",
"requestType": "",
"name": "",
};
pwRequest.name = requestObject.name;
let requestObjectUrl = requestObject.request.url.raw.match(/^(.+:\/\/[^\/]+|{[^\/]+})(\/[^\?]+|).*$/);
pwRequest.url = requestObjectUrl[1];
pwRequest.path = requestObjectUrl[2] ? requestObjectUrl[2] : "";
pwRequest.method = requestObject.request.method;
let itemAuth = requestObject.request.auth ? requestObject.request.auth
: "";
let authType = itemAuth ? itemAuth.type
: "";
if (authType === "basic") {
pwRequest.auth = "Basic Auth";
pwRequest.httpUser = itemAuth.basic[0].key === "username"
? itemAuth.basic[0].value
: itemAuth.basic[1].value;
pwRequest.httpPassword = itemAuth.basic[0].key === "password"
? itemAuth.basic[0].value
: itemAuth.basic[1].value;
} else if (authType === "oauth2") {
pwRequest.auth = "OAuth 2.0";
pwRequest.bearerToken = itemAuth.oauth2[0].key === "accessToken"
? itemAuth.oauth2[0].value
: itemAuth.oauth2[1].value;
} else if (authType === "bearer") {
pwRequest.auth = "Bearer Token";
pwRequest.bearerToken = itemAuth.bearer[0].value;
}
let requestObjectHeaders = requestObject.request.header;
if (requestObjectHeaders) {
pwRequest.headers = requestObjectHeaders;
for (let header of pwRequest.headers) {
delete header.name;
delete header.type;
}
}
let requestObjectParams = requestObject.request.url.query;
if (requestObjectParams) {
pwRequest.params = requestObjectParams;
for (let param of pwRequest.params) {
delete param.disabled;
}
}
if (requestObject.request.body) {
if (requestObject.request.body.mode === "urlencoded") {
let params = requestObject.request.body.urlencoded;
pwRequest.bodyParams = params ? params : [];
for(let param of pwRequest.bodyParams) {
delete param.type;
}
} else if (requestObject.request.body.mode === "raw") {
pwRequest.rawInput = true;
pwRequest.rawParams = requestObject.request.body.raw;
}
}
return pwRequest;
} }
} }
}; };

View File

@@ -57,9 +57,9 @@ export default {
firebase firebase
.auth() .auth()
.signInWithPopup(provider) .signInWithPopup(provider)
.then(res => { .then(({ additionalUserInfo }) => {
if (res.additionalUserInfo.isNewUser) { if (additionalUserInfo.isNewUser) {
this.$toast.info(this.$t("turn_on") + " " + this.$t("sync"), { this.$toast.info(`${this.$t("turn_on")} ${this.$t("sync")}`, {
icon: "sync", icon: "sync",
duration: null, duration: null,
closeOnSwipe: false, closeOnSwipe: false,
@@ -86,9 +86,9 @@ export default {
firebase firebase
.auth() .auth()
.signInWithPopup(provider) .signInWithPopup(provider)
.then(res => { .then(({ additionalUserInfo }) => {
if (res.additionalUserInfo.isNewUser) { if (additionalUserInfo.isNewUser) {
this.$toast.info(this.$t("turn_on") + " " + this.$t("sync"), { this.$toast.info(`${this.$t("turn_on")} ${this.$t("sync")}`, {
icon: "sync", icon: "sync",
duration: null, duration: null,
closeOnSwipe: false, closeOnSwipe: false,

View File

@@ -7,7 +7,9 @@ const DEFAULT_THEME = "twilight";
import ace from "ace-builds"; import ace from "ace-builds";
import * as gql from "graphql"; import * as gql from "graphql";
import { getAutocompleteSuggestions } from "graphql-language-service-interface";
import "ace-builds/webpack-resolver"; import "ace-builds/webpack-resolver";
import "ace-builds/src-noconflict/ext-language_tools";
import debounce from "../../functions/utils/debounce"; import debounce from "../../functions/utils/debounce";
export default { export default {
@@ -46,10 +48,10 @@ export default {
} }
}, },
theme() { theme() {
this.editor.setTheme("ace/theme/" + this.defineTheme()); this.editor.setTheme(`ace/theme/${this.defineTheme()}`);
}, },
lang(value) { lang(value) {
this.editor.getSession().setMode("ace/mode/" + value); this.editor.getSession().setMode(`ace/mode/${value}`);
}, },
options(value) { options(value) {
this.editor.setOptions(value); this.editor.setOptions(value);
@@ -57,12 +59,48 @@ export default {
}, },
mounted() { mounted() {
let langTools = ace.require("ace/ext/language_tools");
const editor = ace.edit(this.$refs.editor, { const editor = ace.edit(this.$refs.editor, {
theme: "ace/theme/" + this.defineTheme(), theme: `ace/theme/${this.defineTheme()}`,
mode: "ace/mode/" + this.lang, mode: `ace/mode/${this.lang}`,
enableBasicAutocompletion: true,
enableLiveAutocompletion: true,
...this.options ...this.options
}); });
const completer = {
getCompletions: (
editor,
_session,
{ row, column },
_prefix,
callback
) => {
if (this.validationSchema) {
const completions = getAutocompleteSuggestions(
this.validationSchema,
editor.getValue(),
{ line: row, character: column }
);
callback(
null,
completions.map(({ label, detail }) => ({
name: label,
value: label,
score: 1.0,
meta: detail
}))
);
} else {
callback(null, []);
}
}
};
langTools.setCompleters([completer]);
if (this.value) editor.setValue(this.value, 1); if (this.value) editor.setValue(this.value, 1);
this.editor = editor; this.editor = editor;
@@ -101,14 +139,14 @@ export default {
if (this.validationSchema) { if (this.validationSchema) {
this.editor.session.setAnnotations( this.editor.session.setAnnotations(
gql.validate(this.validationSchema, doc).map(err => { gql
return { .validate(this.validationSchema, doc)
row: err.locations[0].line - 1, .map(({ locations, message }) => ({
column: err.locations[0].column - 1, row: locations[0].line - 1,
text: err.message, column: locations[0].column - 1,
text: message,
type: "error" type: "error"
}; }))
})
); );
} }
} catch (e) { } catch (e) {

View File

@@ -25,7 +25,7 @@
left: 0; left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
background-color: rgba(0, 0, 0, 0.87); background-color: rgba(0, 0, 0, 0.32);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;

View File

@@ -20,6 +20,7 @@
border-radius: 100%; border-radius: 100%;
border: 3px solid var(--bg-dark-color); border: 3px solid var(--bg-dark-color);
cursor: pointer; cursor: pointer;
transition: all 0.2s ease-in-out;
&.fg { &.fg {
color: var(--act-color); color: var(--act-color);

View File

@@ -121,4 +121,4 @@ export const commonHeaders = [
"X-Requested-With", "X-Requested-With",
"X-Robots-Tag", "X-Robots-Tag",
"X-UA-Compatible" "X-UA-Compatible"
] ];

View File

@@ -1,18 +1,28 @@
import AxiosStrategy from "./strategies/AxiosStrategy"; import AxiosStrategy from "./strategies/AxiosStrategy";
import ExtensionStrategy, {
hasExtensionInstalled
} from "./strategies/ExtensionStrategy";
import FirefoxStrategy from "./strategies/FirefoxStrategy"; import FirefoxStrategy from "./strategies/FirefoxStrategy";
import ChromeStrategy, { hasChromeExtensionInstalled } from "./strategies/ChromeStrategy"; import ChromeStrategy, {
hasChromeExtensionInstalled
} from "./strategies/ChromeStrategy";
const isExtensionsAllowed = ({ state }) => { const isExtensionsAllowed = ({ state }) =>
return typeof state.postwoman.settings.EXTENSIONS_ENABLED === 'undefined' typeof state.postwoman.settings.EXTENSIONS_ENABLED === "undefined" ||
|| state.postwoman.settings.EXTENSIONS_ENABLED; state.postwoman.settings.EXTENSIONS_ENABLED;
}
const runAppropriateStrategy = (req, store) => { const runAppropriateStrategy = (req, store) => {
if (isExtensionsAllowed(store)) { if (isExtensionsAllowed(store)) {
if (hasExtensionInstalled()) {
return ExtensionStrategy(req, store);
}
// The following strategies are deprecated and kept to support older version of the extensions
// Chrome Provides a chrome object for scripts to access // Chrome Provides a chrome object for scripts to access
// Check its availability to say whether you are in Google Chrome // Check its availability to say whether you are in Google Chrome
if (window.chrome && hasChromeExtensionInstalled()) { if (window.chrome && hasChromeExtensionInstalled()) {
return ChromeStrategy(req, store); return ChromeStrategy(req, store);
} }
// The firefox plugin injects a function to send requests through it // The firefox plugin injects a function to send requests through it
// If that is available, then we can use the FirefoxStrategy // If that is available, then we can use the FirefoxStrategy
@@ -22,10 +32,11 @@ const runAppropriateStrategy = (req, store) => {
} }
return AxiosStrategy(req, store); return AxiosStrategy(req, store);
} };
const sendNetworkRequest = (req, store) => const sendNetworkRequest = (req, store) =>
runAppropriateStrategy(req, store) runAppropriateStrategy(req, store).finally(() =>
.finally(() => window.$nuxt.$loading.finish()); window.$nuxt.$loading.finish()
);
export { sendNetworkRequest }; export { sendNetworkRequest };

View File

@@ -3,47 +3,54 @@ const EXTENSION_ID = "amknoiejhlmhancpahfcfcfhllgkpbld";
// Check if the Chrome Extension is present // Check if the Chrome Extension is present
// The Chrome extension injects an empty span to help detection. // The Chrome extension injects an empty span to help detection.
// Also check for the presence of window.chrome object to confirm smooth operations // Also check for the presence of window.chrome object to confirm smooth operations
export const hasChromeExtensionInstalled = () => { export const hasChromeExtensionInstalled = () =>
return document.getElementById("chromePWExtensionDetect") !== null; document.getElementById("chromePWExtensionDetect") !== null;
}
const chromeWithoutProxy = (req, _store) => new Promise((resolve, reject) => { const chromeWithoutProxy = (req, _store) =>
chrome.runtime.sendMessage( new Promise((resolve, reject) => {
EXTENSION_ID, { chrome.runtime.sendMessage(
messageType: "send-req", EXTENSION_ID,
data: { {
config: req messageType: "send-req",
} data: {
}, (message) => { config: req
if (message.data.error) { }
reject(message.data.error); },
} else { ({ data }) => {
resolve(message.data.response); if (data.error) {
} reject(data.error);
} } else {
); resolve(data.response);
});
const chromeWithProxy = (req, { state }) => new Promise((resolve, reject) => {
chrome.runtime.sendMessage(
EXTENSION_ID, {
messageType: "send-req",
data: {
config: {
method: "post",
url: state.postwoman.settings.PROXY_URL || "https://postwoman.apollotv.xyz/",
data: req
} }
} }
}, (message) => { );
if (message.data.error) { });
reject(error);
} else { const chromeWithProxy = (req, { state }) =>
resolve(message.data.response.data); new Promise((resolve, reject) => {
chrome.runtime.sendMessage(
EXTENSION_ID,
{
messageType: "send-req",
data: {
config: {
method: "post",
url:
state.postwoman.settings.PROXY_URL ||
"https://postwoman.apollotv.xyz/",
data: req
}
}
},
({ data }) => {
if (data.error) {
reject(error);
} else {
resolve(data.response.data);
}
} }
} );
) });
});
const chromeStrategy = (req, store) => { const chromeStrategy = (req, store) => {
if (store.state.postwoman.settings.PROXY_ENABLED) { if (store.state.postwoman.settings.PROXY_ENABLED) {
@@ -51,6 +58,6 @@ const chromeStrategy = (req, store) => {
} else { } else {
return chromeWithoutProxy(req, store); return chromeWithoutProxy(req, store);
} }
} };
export default chromeStrategy; export default chromeStrategy;

View File

@@ -0,0 +1,26 @@
export const hasExtensionInstalled = () =>
typeof window.__POSTWOMAN_EXTENSION_HOOK__ !== "undefined";
const extensionWithProxy = async (req, { state }) => {
const { data } = await window.__POSTWOMAN_EXTENSION_HOOK__.sendRequest({
method: "post",
url:
state.postwoman.settings.PROXY_URL || "https://postwoman.apollotv.xyz/",
data: req
});
return data;
};
const extensionWithoutProxy = async (req, _store) => {
const res = await window.__POSTWOMAN_EXTENSION_HOOK__.sendRequest(req);
return res;
};
const extensionStrategy = (req, store) => {
if (store.state.postwoman.settings.PROXY_ENABLED) {
return extensionWithProxy(req, store);
}
return extensionWithoutProxy(req, store);
};
export default extensionStrategy;

View File

@@ -230,6 +230,7 @@ export default {
payload: "Payload", payload: "Payload",
choose_file: "Choose a file", choose_file: "Choose a file",
file_imported: "File imported", file_imported: "File imported",
import_failed: "Import failed",
f12_details: "(F12 for details)", f12_details: "(F12 for details)",
we_use_cookies: "We use cookies", we_use_cookies: "We use cookies",
copied_to_clipboard: "Copied to clipboard", copied_to_clipboard: "Copied to clipboard",

View File

@@ -247,6 +247,11 @@
<i class="material-icons">brush</i> <i class="material-icons">brush</i>
</a> </a>
</li> </li>
<li>
<a href="#extensions" v-tooltip.right="$t('extensions')">
<i class="material-icons">extensions</i>
</a>
</li>
<li> <li>
<a href="#proxy" v-tooltip.right="$t('proxy')"> <a href="#proxy" v-tooltip.right="$t('proxy')">
<i class="material-icons">public</i> <i class="material-icons">public</i>
@@ -408,7 +413,7 @@
<div class="flex-wrap"> <div class="flex-wrap">
<span v-if="version.name" class="mono"> <span v-if="version.name" class="mono">
<a <a
class="link" class="footer-link"
:href=" :href="
'https://github.com/liyasthomas/postwoman/releases/tag/' + 'https://github.com/liyasthomas/postwoman/releases/tag/' +
version.name version.name
@@ -420,7 +425,7 @@
{{ version.name }} {{ version.name }}
</a> </a>
<a <a
class="link hide-on-small-screen" class="footer-link hide-on-small-screen"
href="https://www.netlify.com" href="https://www.netlify.com"
target="_blank" target="_blank"
rel="noopener" rel="noopener"
@@ -660,7 +665,7 @@
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss">
.link { .footer-link {
margin: 8px 16px; margin: 8px 16px;
} }
</style> </style>
@@ -668,7 +673,7 @@
<script> <script>
import intializePwa from "../assets/js/pwa"; import intializePwa from "../assets/js/pwa";
import * as version from "../.postwoman/version.json"; import * as version from "../.postwoman/version.json";
import { hasChromeExtensionInstalled } from "../functions/strategies/ChromeStrategy"; import { hasExtensionInstalled } from "../functions/strategies/ExtensionStrategy";
import firebase from "firebase/app"; import firebase from "firebase/app";
import { fb } from "../functions/fb"; import { fb } from "../functions/fb";
@@ -715,7 +720,7 @@ export default {
.then(() => {}) .then(() => {})
.catch(console.error); .catch(console.error);
} else { } else {
// fallback // fallback
} }
} }
}, },
@@ -730,8 +735,7 @@ export default {
showExtensions: false, showExtensions: false,
showShortcuts: false, showShortcuts: false,
showSupport: false, showSupport: false,
firefoxExtInstalled: window.firefoxExtSendRequest, extensionInstalled: hasExtensionInstalled(),
chromeExtInstalled: window.chrome && hasChromeExtensionInstalled(),
fb, fb,
navigatorShare: navigator.share navigatorShare: navigator.share
}; };
@@ -794,8 +798,7 @@ export default {
let showExtensionsToast = let showExtensionsToast =
localStorage.getItem("showExtensionsToast") === "yes"; localStorage.getItem("showExtensionsToast") === "yes";
if ( if (
!this.firefoxExtInstalled && !this.extensionInstalled &&
!this.chromeExtInstalled &&
!showExtensionsToast !showExtensionsToast
) { ) {
setTimeout(() => { setTimeout(() => {

136
package-lock.json generated
View File

@@ -991,9 +991,9 @@
} }
}, },
"@firebase/firestore": { "@firebase/firestore": {
"version": "1.10.2", "version": "1.11.1",
"resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-1.10.2.tgz", "resolved": "https://registry.npmjs.org/@firebase/firestore/-/firestore-1.11.1.tgz",
"integrity": "sha512-Ay9V7eLYNEt12STCfmUxtyu4IBWIgOONzxoRUnkK1nmNbvket7XhSCfij4P4pi3qx4kdpp+hzjUl6ndVbh7y5Q==", "integrity": "sha512-bzGBY1JgzVJs9rdjWNl9ZnJxkqt2ty8oBIplHYCkpa+lp5RNpyvwmuZ6D6vFW67f/2+kEN8Wci82KMIvnoBVtg==",
"requires": { "requires": {
"@firebase/component": "0.1.5", "@firebase/component": "0.1.5",
"@firebase/firestore-types": "1.9.1", "@firebase/firestore-types": "1.9.1",
@@ -1011,9 +1011,9 @@
"integrity": "sha512-w3pT+RMQOORS8Tvf6wCaW8sq8hklPS4FkWSGCyo/gIbATP7pG8rvQDihN1x6D3if1jILWiZ/uPyl0eazm+MGzw==" "integrity": "sha512-w3pT+RMQOORS8Tvf6wCaW8sq8hklPS4FkWSGCyo/gIbATP7pG8rvQDihN1x6D3if1jILWiZ/uPyl0eazm+MGzw=="
}, },
"@firebase/functions": { "@firebase/functions": {
"version": "0.4.32", "version": "0.4.34",
"resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.4.32.tgz", "resolved": "https://registry.npmjs.org/@firebase/functions/-/functions-0.4.34.tgz",
"integrity": "sha512-0v8YkEElryo7Apx1S+eTUBR/yz/Gatj064hy37AWNN9n5oUjRyrkwl40/YywFPw15AZPB8ItoEx+wJBnyFjgUw==", "integrity": "sha512-TbgNlYLJudpugjEPz6JNcYWOBPXuq8DSBvztxGnP/bxEE4wqR9MAjADwJ0QfJYM8llbi/G9Vp9XbVKj+Jdszpg==",
"requires": { "requires": {
"@firebase/component": "0.1.5", "@firebase/component": "0.1.5",
"@firebase/functions-types": "0.3.14", "@firebase/functions-types": "0.3.14",
@@ -1050,9 +1050,9 @@
"integrity": "sha512-T7I/0+IQrlPAm/uUw6xeyJH5Msi8P6in/0LUtz2XQn2+LVBqyatlr+Nod9AldDCZehwLySEAFhXlqhb3BrI5GA==" "integrity": "sha512-T7I/0+IQrlPAm/uUw6xeyJH5Msi8P6in/0LUtz2XQn2+LVBqyatlr+Nod9AldDCZehwLySEAFhXlqhb3BrI5GA=="
}, },
"@firebase/messaging": { "@firebase/messaging": {
"version": "0.6.4", "version": "0.6.6",
"resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.6.4.tgz", "resolved": "https://registry.npmjs.org/@firebase/messaging/-/messaging-0.6.6.tgz",
"integrity": "sha512-QKoK5gskZ9cECOa5nnp2oXoP3vmVOyzrEj3x0vHu1HsZhCg6EgRiJ9yO4LeTwoVcwFKDMkuNNPJZ8USOy2fdtw==", "integrity": "sha512-acCZ9gXKYecLdPAoQv9MvaMKO0a7C636AxRHW+vHkJ+rId5AgoZqIqn99y3tHv5LAkm+BrGqOva7SOQBhEWkiA==",
"requires": { "requires": {
"@firebase/component": "0.1.5", "@firebase/component": "0.1.5",
"@firebase/installations": "0.4.2", "@firebase/installations": "0.4.2",
@@ -3822,6 +3822,27 @@
"sha.js": "^2.4.8" "sha.js": "^2.4.8"
} }
}, },
"cross-fetch": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.2.tgz",
"integrity": "sha1-pH/09/xxLauo9qaVoRyUhEDUVyM=",
"requires": {
"node-fetch": "2.1.2",
"whatwg-fetch": "2.0.4"
},
"dependencies": {
"node-fetch": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz",
"integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U="
},
"whatwg-fetch": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz",
"integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng=="
}
}
},
"cross-spawn": { "cross-spawn": {
"version": "6.0.5", "version": "6.0.5",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
@@ -5194,19 +5215,19 @@
} }
}, },
"firebase": { "firebase": {
"version": "7.8.2", "version": "7.9.1",
"resolved": "https://registry.npmjs.org/firebase/-/firebase-7.8.2.tgz", "resolved": "https://registry.npmjs.org/firebase/-/firebase-7.9.1.tgz",
"integrity": "sha512-qB/YopC6PVYTe2Q8hSwDD9CLdQHiMN1HUj/rxFxoICJR1VGkHP2KUvx2gv990V7CwzXIruLWoz9MwCOHFj9D0w==", "integrity": "sha512-yF80JPxLDXypBxhOeJDKULeP1MwZ/+Clovx3JZOvzH9yoRhIZZBx17/vkQFb7d0b+ICqwrKIofgpPzPef+CMpw==",
"requires": { "requires": {
"@firebase/analytics": "0.2.13", "@firebase/analytics": "0.2.13",
"@firebase/app": "0.5.4", "@firebase/app": "0.5.4",
"@firebase/app-types": "0.5.1", "@firebase/app-types": "0.5.1",
"@firebase/auth": "0.13.5", "@firebase/auth": "0.13.5",
"@firebase/database": "0.5.21", "@firebase/database": "0.5.21",
"@firebase/firestore": "1.10.2", "@firebase/firestore": "1.11.1",
"@firebase/functions": "0.4.32", "@firebase/functions": "0.4.34",
"@firebase/installations": "0.4.2", "@firebase/installations": "0.4.2",
"@firebase/messaging": "0.6.4", "@firebase/messaging": "0.6.6",
"@firebase/performance": "0.2.32", "@firebase/performance": "0.2.32",
"@firebase/polyfill": "0.3.31", "@firebase/polyfill": "0.3.31",
"@firebase/remote-config": "0.1.13", "@firebase/remote-config": "0.1.13",
@@ -5589,6 +5610,79 @@
"iterall": "^1.2.2" "iterall": "^1.2.2"
} }
}, },
"graphql-config": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/graphql-config/-/graphql-config-2.2.1.tgz",
"integrity": "sha512-U8+1IAhw9m6WkZRRcyj8ZarK96R6lQBQ0an4lp76Ps9FyhOXENC5YQOxOFGm5CxPrX2rD0g3Je4zG5xdNJjwzQ==",
"requires": {
"graphql-import": "^0.7.1",
"graphql-request": "^1.5.0",
"js-yaml": "^3.10.0",
"lodash": "^4.17.4",
"minimatch": "^3.0.4"
}
},
"graphql-import": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/graphql-import/-/graphql-import-0.7.1.tgz",
"integrity": "sha512-YpwpaPjRUVlw2SN3OPljpWbVRWAhMAyfSba5U47qGMOSsPLi2gYeJtngGpymjm9nk57RFWEpjqwh4+dpYuFAPw==",
"requires": {
"lodash": "^4.17.4",
"resolve-from": "^4.0.0"
},
"dependencies": {
"resolve-from": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="
}
}
},
"graphql-language-service-interface": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/graphql-language-service-interface/-/graphql-language-service-interface-2.3.3.tgz",
"integrity": "sha512-SMUbbiHbD19ffyDrucR+vwyaKYhDcTgbBFDJu9Z4TBa5XaksmyiurB3f+pWlIkuFvogBvW3JDiiJJlUW7awivg==",
"requires": {
"graphql-config": "2.2.1",
"graphql-language-service-parser": "^1.5.2",
"graphql-language-service-types": "^1.5.2",
"graphql-language-service-utils": "^2.3.3"
}
},
"graphql-language-service-parser": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/graphql-language-service-parser/-/graphql-language-service-parser-1.5.2.tgz",
"integrity": "sha512-kModfvwX5XiT+tYRhh8d6X+rb5Zq9zFQVdcoVlQJvoIW7U6SkxUAeO5Ei9OI3KOMH5r8wyfmXflBZ+xUbJySJw==",
"requires": {
"graphql-config": "2.2.1",
"graphql-language-service-types": "^1.5.2"
}
},
"graphql-language-service-types": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/graphql-language-service-types/-/graphql-language-service-types-1.5.2.tgz",
"integrity": "sha512-WOFHBZX1K41svohPTmhOcKg+zz27d6ULFuZ8mzkiJ9nIpGKueAPyh7/xR0VZNBUAfDzTCbE6wQZxsPl5Kvd7IA==",
"requires": {
"graphql-config": "2.2.1"
}
},
"graphql-language-service-utils": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/graphql-language-service-utils/-/graphql-language-service-utils-2.3.3.tgz",
"integrity": "sha512-uHLdIbQpKkE1V2WA12DRMXrUZpPD3ZKPOuH3MHlNg+j9AEe1y83chA4yP5DQqR+ARdMpefz4FJHvEjQr9alXYw==",
"requires": {
"graphql-config": "2.2.1",
"graphql-language-service-types": "^1.5.2"
}
},
"graphql-request": {
"version": "1.8.2",
"resolved": "https://registry.npmjs.org/graphql-request/-/graphql-request-1.8.2.tgz",
"integrity": "sha512-dDX2M+VMsxXFCmUX0Vo0TopIZIX4ggzOtiCsThgtrKR4niiaagsGTDIHj3fsOMFETpa064vzovI+4YV4QnMbcg==",
"requires": {
"cross-fetch": "2.2.2"
}
},
"grpc": { "grpc": {
"version": "1.24.2", "version": "1.24.2",
"resolved": "https://registry.npmjs.org/grpc/-/grpc-1.24.2.tgz", "resolved": "https://registry.npmjs.org/grpc/-/grpc-1.24.2.tgz",
@@ -9676,9 +9770,9 @@
}, },
"dependencies": { "dependencies": {
"@types/node": { "@types/node": {
"version": "10.17.15", "version": "10.17.16",
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.15.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.16.tgz",
"integrity": "sha512-daFGV9GSs6USfPgxceDA8nlSe48XrVCJfDeYm7eokxq/ye7iuOH87hKXgMtEAVLFapkczbZsx868PMDT1Y0a6A==" "integrity": "sha512-A4283YSA1OmnIivcpy/4nN86YlnKRiQp8PYwI2KdPCONEBN093QTb0gCtERtkLyVNGKKIGazTZ2nAmVzQU51zA=="
} }
} }
}, },
@@ -12087,9 +12181,9 @@
"integrity": "sha512-GVbwInwnqkVxQ4GU/XYeQt1e0dAXL8sF5Hr1H/coCBbYUan5xP0G2mEz/HRDf1lt73rFQAN/bJcLTOKkqiM6tg==" "integrity": "sha512-GVbwInwnqkVxQ4GU/XYeQt1e0dAXL8sF5Hr1H/coCBbYUan5xP0G2mEz/HRDf1lt73rFQAN/bJcLTOKkqiM6tg=="
}, },
"vue-virtual-scroll-list": { "vue-virtual-scroll-list": {
"version": "1.4.4", "version": "1.4.6",
"resolved": "https://registry.npmjs.org/vue-virtual-scroll-list/-/vue-virtual-scroll-list-1.4.4.tgz", "resolved": "https://registry.npmjs.org/vue-virtual-scroll-list/-/vue-virtual-scroll-list-1.4.6.tgz",
"integrity": "sha512-wU7FDpd9Xy4f62pf8SBg/ak21jMI/pdx4s4JPah+z/zuhmeAafQgp8BjtZvvt+b0BZOsOS1FJuCfUH7azTkivQ==" "integrity": "sha512-YVPVy+aNDgTq151ONOR9jA/X0BGqcXXyX3E8eyAUvEWDNy2cRScqHA9tUqS+FPszSYEY+Bgxto9Rkd99AN5xsQ=="
}, },
"vuefire": { "vuefire": {
"version": "2.2.1", "version": "2.2.1",

View File

@@ -26,12 +26,13 @@
"@nuxtjs/sitemap": "^2.0.1", "@nuxtjs/sitemap": "^2.0.1",
"@nuxtjs/toast": "^3.3.0", "@nuxtjs/toast": "^3.3.0",
"ace-builds": "^1.4.8", "ace-builds": "^1.4.8",
"firebase": "^7.8.2", "firebase": "^7.9.1",
"graphql": "^14.6.0", "graphql": "^14.6.0",
"graphql-language-service-interface": "^2.3.3",
"nuxt": "^2.11.0", "nuxt": "^2.11.0",
"nuxt-i18n": "^6.5.0", "nuxt-i18n": "^6.5.0",
"v-tooltip": "^2.0.3", "v-tooltip": "^2.0.3",
"vue-virtual-scroll-list": "^1.4.4", "vue-virtual-scroll-list": "^1.4.6",
"vuefire": "^2.2.1", "vuefire": "^2.2.1",
"vuejs-auto-complete": "^0.9.0", "vuejs-auto-complete": "^0.9.0",
"vuex-persist": "^2.2.0", "vuex-persist": "^2.2.0",

View File

@@ -247,7 +247,6 @@
<span> <span>
<pw-toggle :on="rawInput" @change="rawInput = $event"> <pw-toggle :on="rawInput" @change="rawInput = $event">
{{ $t("raw_input") }} {{ $t("raw_input") }}
{{ rawInput ? $t("enabled") : $t("disabled") }}
</pw-toggle> </pw-toggle>
</span> </span>
<div> <div>
@@ -459,7 +458,8 @@
:disabled="!isValidURL" :disabled="!isValidURL"
v-tooltip.bottom="$t('copy_request_link')" v-tooltip.bottom="$t('copy_request_link')"
> >
<i class="material-icons">file_copy</i> <i v-if="navigatorShare" class="material-icons">share</i>
<i v-else class="material-icons">file_copy</i>
</button> </button>
<button <button
class="icon" class="icon"
@@ -1516,7 +1516,8 @@ export default {
fb, fb,
customMethod: false, customMethod: false,
files: [], files: [],
filenames: "" filenames: "",
navigatorShare: navigator.share
}; };
}, },
watch: { watch: {

View File

@@ -155,6 +155,7 @@
</li> </li>
</ul> </ul>
</pw-section> </pw-section>
<pw-section class="blue" :label="$t('proxy')" ref="proxy"> <pw-section class="blue" :label="$t('proxy')" ref="proxy">
<ul> <ul>
<li> <li>
@@ -206,7 +207,12 @@
{{ $t("postwoman_official_proxy_hosting") }} {{ $t("postwoman_official_proxy_hosting") }}
<br /> <br />
{{ $t("read_the") }} {{ $t("read_the") }}
<a href="https://apollotv.xyz/legal" target="_blank" rel="noopener"> <a
class="link"
href="https://apollotv.xyz/legal"
target="_blank"
rel="noopener"
>
{{ $t("apollotv_privacy_policy") }} </a {{ $t("apollotv_privacy_policy") }} </a
>. >.
</p> </p>
@@ -270,7 +276,7 @@ export default {
aceEditor: "vibrant_ink" aceEditor: "vibrant_ink"
}, },
{ {
color: "var(--bg-color)", color: "var(--ac-color)",
name: this.$t("auto_system"), name: this.$t("auto_system"),
vibrant: window.matchMedia("(prefers-color-scheme: light)").matches, vibrant: window.matchMedia("(prefers-color-scheme: light)").matches,
class: "auto", class: "auto",

View File

@@ -61,7 +61,7 @@ export const SETTINGS_KEYS = [
/** /**
* A boolean value indicating whether to use the browser extensions * A boolean value indicating whether to use the browser extensions
* to run the requests * to run the requests
*/ */
"EXTENSIONS_ENABLED" "EXTENSIONS_ENABLED"
]; ];
@@ -180,7 +180,9 @@ export const mutations = {
addNewCollection({ collections }, collection) { addNewCollection({ collections }, collection) {
const { name } = collection; const { name } = collection;
const duplicateCollection = collections.some(item => item.name.toLowerCase() === name.toLowerCase()); const duplicateCollection = collections.some(
item => item.name.toLowerCase() === name.toLowerCase()
);
if (duplicateCollection) { if (duplicateCollection) {
this.$toast.info("Duplicate collection"); this.$toast.info("Duplicate collection");
return; return;
@@ -199,9 +201,10 @@ export const mutations = {
}, },
editCollection({ collections }, payload) { editCollection({ collections }, payload) {
const { collection, collectionIndex } = payload; const { collection: { name }, collectionIndex } = payload;
const { name } = collection; const duplicateCollection = collections.some(
const duplicateCollection = collections.some(item => item.name.toLowerCase() === name.toLowerCase()); item => item.name.toLowerCase() === name.toLowerCase()
);
if (duplicateCollection) { if (duplicateCollection) {
this.$toast.info("Duplicate collection"); this.$toast.info("Duplicate collection");
return; return;