Merge pull request #104 from simple-login/feat/reverse-alias
Add reverse-alias screen
This commit is contained in:
Generated
+741
-410
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -49,9 +49,9 @@
|
||||
"ejs": "^2.6.1",
|
||||
"file-loader": "^1.1.11",
|
||||
"mini-css-extract-plugin": "^0.4.4",
|
||||
"node-sass": "^4.13.1",
|
||||
"node-sass": "^6.0.1",
|
||||
"prettier": "^2.0.5",
|
||||
"sass-loader": "^7.1.0",
|
||||
"sass-loader": "^10.1.1",
|
||||
"vue-loader": "^15.4.2",
|
||||
"vue-template-compiler": "^2.6.14",
|
||||
"web-ext-types": "^2.1.0",
|
||||
|
||||
@@ -38,12 +38,12 @@
|
||||
step.
|
||||
</p>
|
||||
<br />
|
||||
<button @click="goToCreateNewAccount()" class="btn btn-primary">
|
||||
<a :href="url.createNewAccount" class="btn btn-primary">
|
||||
Create a new account
|
||||
</button>
|
||||
<button @click="goToLogin()" class="btn btn-outline-primary">
|
||||
</a>
|
||||
<a :href="url.login" class="btn btn-outline-primary">
|
||||
I already have account
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="content" v-if="step === 3">
|
||||
@@ -67,12 +67,12 @@
|
||||
<img
|
||||
v-if="isChrome"
|
||||
src="../images/chrome-permission-screenshot.png"
|
||||
style="width: 400px"
|
||||
style="width: 400px;"
|
||||
/>
|
||||
<img
|
||||
v-else
|
||||
src="../images/firefox-permission-screenshot.png"
|
||||
style="width: 400px"
|
||||
style="width: 400px;"
|
||||
/>
|
||||
|
||||
<p>
|
||||
@@ -84,7 +84,7 @@
|
||||
<img
|
||||
alt="SimpleLogin Button demo"
|
||||
src="../images/sl-button-demo.png"
|
||||
style="width: 400px"
|
||||
style="width: 400px;"
|
||||
class="mb-3"
|
||||
/>
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
<button
|
||||
@click="nextStep()"
|
||||
class="btn"
|
||||
style="color: #888; font-size: 0.8em"
|
||||
style="color: #888; font-size: 0.8em;"
|
||||
>
|
||||
Skip
|
||||
</button>
|
||||
@@ -119,20 +119,20 @@
|
||||
<img
|
||||
alt="SimpleLogin"
|
||||
src="../images/icon-simplelogin.png"
|
||||
style="height: 1.2em"
|
||||
style="height: 1.2em;"
|
||||
/>
|
||||
icon at the corner of your browser.
|
||||
</p>
|
||||
<p
|
||||
v-if="isChrome"
|
||||
class="alert alert-primary"
|
||||
style="border-left: 5px #467fcf solid"
|
||||
style="border-left: 5px #467fcf solid;"
|
||||
>
|
||||
Note: this icon maybe hidden under
|
||||
<img
|
||||
alt="Extension Menu"
|
||||
src="../images/icon-puzzle.png"
|
||||
style="height: 1.2em"
|
||||
style="height: 1.2em;"
|
||||
/>
|
||||
button.
|
||||
</p>
|
||||
@@ -157,29 +157,38 @@ import EventManager from "../popup/EventManager";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
step: window.location.href.match(/#step3/) ? 3 : 1,
|
||||
step: 1,
|
||||
isChrome:
|
||||
/Chrome/.test(navigator.userAgent) &&
|
||||
/Google Inc/.test(navigator.vendor),
|
||||
isAuthenticated: false,
|
||||
userName: "",
|
||||
url: {
|
||||
createNewAccount: "",
|
||||
login: "",
|
||||
},
|
||||
};
|
||||
},
|
||||
async mounted() {
|
||||
// get URL for buttons
|
||||
const apiUrl = await SLStorage.get(SLStorage.SETTINGS.API_URL);
|
||||
this.url.createNewAccount = `${apiUrl}/auth/register?next=%2Fdashboard%2Fsetup_done`;
|
||||
this.url.login = `${apiUrl}/dashboard/setup_done`;
|
||||
|
||||
// maybe user redirected from the setup_done page
|
||||
if (this.step === 3) {
|
||||
await this.tryGetUserInfo();
|
||||
}
|
||||
|
||||
// update setup step
|
||||
const self = this;
|
||||
const updateStep = function () {
|
||||
self.step = window.location.href.match(/#step3/) ? 3 : 1;
|
||||
};
|
||||
window.addEventListener("hashchange", updateStep, false);
|
||||
updateStep();
|
||||
},
|
||||
methods: {
|
||||
async goToCreateNewAccount() {
|
||||
const apiUrl = await SLStorage.get(SLStorage.SETTINGS.API_URL);
|
||||
window.location.href = `${apiUrl}/auth/register?next=%2Fdashboard%2Fsetup_done`;
|
||||
},
|
||||
async goToLogin() {
|
||||
const apiUrl = await SLStorage.get(SLStorage.SETTINGS.API_URL);
|
||||
window.location.href = `${apiUrl}/dashboard/setup_done`;
|
||||
},
|
||||
toStep(i) {
|
||||
this.step = i;
|
||||
},
|
||||
|
||||
@@ -29,6 +29,10 @@ const API_ROUTE = {
|
||||
TOGGLE_ALIAS: { method: "POST", path: "/api/aliases/:alias_id/toggle" },
|
||||
EDIT_ALIAS: { method: "PUT", path: "/api/aliases/:alias_id" },
|
||||
DELETE_ALIAS: { method: "DELETE", path: "/api/aliases/:alias_id" },
|
||||
CREATE_REVERSE_ALIAS: {
|
||||
method: "POST",
|
||||
path: "/api/aliases/:alias_id/contacts",
|
||||
},
|
||||
GET_API_KEY_FROM_COOKIE: { method: "POST", path: "/api/api_key" },
|
||||
};
|
||||
|
||||
|
||||
@@ -159,6 +159,14 @@ em {
|
||||
.btn-svg {
|
||||
cursor: pointer;
|
||||
padding: 5px;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
/* send btn*/
|
||||
.btn-send {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
color: #b02a8f;
|
||||
}
|
||||
|
||||
/* more options */
|
||||
|
||||
@@ -18,6 +18,7 @@ import SelfHostSetting from "./components/SelfHostSetting";
|
||||
import ApiKeySetting from "./components/ApiKeySetting";
|
||||
import Main from "./components/Main";
|
||||
import NewAliasResult from "./components/NewAliasResult";
|
||||
import ReverseAlias from "./components/ReverseAlias";
|
||||
import AppSettings from "./components/AppSettings";
|
||||
import Utils from "./Utils";
|
||||
import APIService from "./APIService";
|
||||
@@ -30,6 +31,7 @@ const components = {
|
||||
ApiKeySetting,
|
||||
Main,
|
||||
NewAliasResult,
|
||||
ReverseAlias,
|
||||
AppSettings,
|
||||
};
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ const PATH = {
|
||||
LOGIN: "/login",
|
||||
API_KEY_SETTING: "/api-key-setting",
|
||||
SELF_HOST_SETTING: "/self-host-setting",
|
||||
REVERSE_ALIAS: "/reverse-alias",
|
||||
APP_SETTINGS: "/app-settings",
|
||||
};
|
||||
|
||||
@@ -39,6 +40,10 @@ class Navigation {
|
||||
path: Navigation.PATH.NEW_ALIAS_RESULT,
|
||||
component: components.NewAliasResult,
|
||||
},
|
||||
{
|
||||
path: Navigation.PATH.REVERSE_ALIAS,
|
||||
component: components.ReverseAlias,
|
||||
},
|
||||
{
|
||||
path: Navigation.PATH.APP_SETTINGS,
|
||||
component: components.AppSettings,
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
<textarea-autosize
|
||||
placeholder="Note, can be anything to help you remember why you created this alias. This field is optional."
|
||||
class="form-control"
|
||||
style="width: 100%"
|
||||
style="width: 100%;"
|
||||
v-model="moreOptions.note"
|
||||
:disabled="loading"
|
||||
></textarea-autosize>
|
||||
@@ -38,7 +38,7 @@
|
||||
From Name
|
||||
<font-awesome-icon
|
||||
v-b-tooltip.hover.top="
|
||||
'This name is used when you send or reply from alias'
|
||||
'This name is used when you send or reply from alias. You may need to use a pseudonym because the receiver can see it.'
|
||||
"
|
||||
icon="question-circle"
|
||||
/>
|
||||
@@ -69,7 +69,7 @@
|
||||
|
||||
<button
|
||||
class="btn btn-sm btn-delete"
|
||||
style="color: #dc3545"
|
||||
style="color: #dc3545;"
|
||||
v-on:click="handleClickDelete"
|
||||
:disabled="loading"
|
||||
>
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
<template>
|
||||
<div class="header">
|
||||
<div class="row mt-2 pb-2 ml-3 mr-2" style="border-bottom: 1px #eee solid">
|
||||
<div class="row mt-2 pb-2 ml-3 mr-2" style="border-bottom: 1px #eee solid;">
|
||||
<div>
|
||||
<div
|
||||
v-on:click="navigateBack()"
|
||||
v-bind:class="{ back: canBack }"
|
||||
style="display: inline-block"
|
||||
style="display: inline-block;"
|
||||
>
|
||||
<img
|
||||
v-if="canBack"
|
||||
src="/images/back-button.svg"
|
||||
style="height: 20px"
|
||||
style="height: 20px;"
|
||||
/>
|
||||
<img
|
||||
class="sl-logo"
|
||||
src="/images/horizontal-logo.svg"
|
||||
style="height: 18px"
|
||||
style="height: 18px;"
|
||||
/>
|
||||
</div>
|
||||
<div class="beta-badge" v-if="isBeta">BETA</div>
|
||||
@@ -53,7 +53,7 @@
|
||||
:href="apiUrl + '/dashboard/'"
|
||||
target="_blank"
|
||||
class="dashboard-btn float-right"
|
||||
style="padding: 0.25rem 0.5rem; font-size: 0.875rem"
|
||||
style="padding: 0.25rem 0.5rem; font-size: 0.875rem;"
|
||||
title="Dashboard"
|
||||
v-b-tooltip.hover
|
||||
:disabled="!useCompactLayout"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="content">
|
||||
<!-- Login/register screen -->
|
||||
<div v-if="!isShowMfa" class="p-6 container" style="min-height: 350px">
|
||||
<div v-if="!isShowMfa" class="p-6 container" style="min-height: 350px;">
|
||||
<h1 class="h5 mb-3">
|
||||
Welcome to
|
||||
<a href="https://simplelogin.io" target="_blank"
|
||||
@@ -52,7 +52,7 @@
|
||||
<!-- END Login/register screen -->
|
||||
|
||||
<!-- MFA screen -->
|
||||
<div v-else class="p-6 container" style="min-height: 350px">
|
||||
<div v-else class="p-6 container" style="min-height: 350px;">
|
||||
<div class="p-3">
|
||||
<div class="mb-2">
|
||||
Your account is protected with Two Factor Authentication. <br />
|
||||
@@ -63,7 +63,7 @@
|
||||
<p>Please enter the 2FA code from your 2FA authenticator</p>
|
||||
</div>
|
||||
|
||||
<div style="margin: auto">
|
||||
<div style="margin: auto;">
|
||||
<input
|
||||
v-model="mfaCode"
|
||||
v-on:keyup.enter="submitMfaCode"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<!-- Main Page -->
|
||||
<div class="container">
|
||||
<div v-if="recommendation.show" class="text-center">
|
||||
<div class="" style="font-size: 12px">
|
||||
<div class="" style="font-size: 12px;">
|
||||
You created this alias on this website before:
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
@@ -27,14 +27,14 @@
|
||||
<div>
|
||||
<p
|
||||
class="font-weight-bold mt-2 align-self-center"
|
||||
style="display: inline-block"
|
||||
style="display: inline-block;"
|
||||
>
|
||||
New Alias
|
||||
</p>
|
||||
|
||||
<button
|
||||
:disabled="loading || !canCreate"
|
||||
style="margin-left: 15px"
|
||||
style="margin-left: 15px;"
|
||||
class="btn btn-outline-primary btn-sm"
|
||||
title="Generate a totally random alias."
|
||||
@click="createRandomAlias"
|
||||
@@ -49,7 +49,7 @@
|
||||
<div class="row mb-2">
|
||||
<div
|
||||
class="col align-self-start input-group-sm"
|
||||
style="padding-right: 0"
|
||||
style="padding-right: 0;"
|
||||
>
|
||||
<input
|
||||
v-model="aliasPrefix"
|
||||
@@ -63,7 +63,7 @@
|
||||
|
||||
<div
|
||||
class="col align-self-start input-group-sm"
|
||||
style="padding-left: 5px; padding-right: 5px"
|
||||
style="padding-left: 5px; padding-right: 5px;"
|
||||
>
|
||||
<select
|
||||
v-model="signedSuffix"
|
||||
@@ -82,7 +82,7 @@
|
||||
|
||||
<button
|
||||
:disabled="loading || !canCreate"
|
||||
style="margin-right: 15px"
|
||||
style="margin-right: 15px;"
|
||||
class="btn btn-primary btn-sm align-self-start"
|
||||
>
|
||||
Create
|
||||
@@ -90,7 +90,7 @@
|
||||
</div>
|
||||
<div
|
||||
class="row text-danger"
|
||||
style="font-size: 12px"
|
||||
style="font-size: 12px;"
|
||||
v-if="aliasPrefixError != ''"
|
||||
>
|
||||
<div class="col">
|
||||
@@ -100,13 +100,13 @@
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="mb-1 text-center" v-if="aliasPrefix" style="font-size: 12px">
|
||||
<div class="mb-1 text-center" v-if="aliasPrefix" style="font-size: 12px;">
|
||||
You're about to create alias
|
||||
<span class="text-primary">{{ aliasPrefix }}{{ signedSuffix[0] }}</span>
|
||||
</div>
|
||||
|
||||
<div v-if="!canCreate">
|
||||
<p class="text-danger" style="font-size: 14px">
|
||||
<p class="text-danger" style="font-size: 14px;">
|
||||
You have reached limit number of email aliases in free plan, please
|
||||
<a :href="apiUrl + '/dashboard/pricing'" target="_blank">upgrade</a>
|
||||
or reuse one of the existing aliases.
|
||||
@@ -119,7 +119,7 @@
|
||||
Or use an existing alias
|
||||
</div>
|
||||
|
||||
<div class="mx-auto" style="max-width: 60%">
|
||||
<div class="mx-auto" style="max-width: 60%;">
|
||||
<input
|
||||
v-model="searchString"
|
||||
v-on:keyup.enter="loadAlias"
|
||||
@@ -133,7 +133,7 @@
|
||||
v-if="searchString"
|
||||
@click="resetSearch"
|
||||
class="float-right"
|
||||
style="color: blue; border: none; padding: 0; background: none"
|
||||
style="color: blue; border: none; padding: 0; background: none;"
|
||||
>
|
||||
Reset
|
||||
</button>
|
||||
@@ -157,7 +157,7 @@
|
||||
</a>
|
||||
<div class="list-item-email-fade" />
|
||||
</div>
|
||||
<div style="white-space: nowrap">
|
||||
<div style="white-space: nowrap;">
|
||||
<toggle-button
|
||||
:value="alias.enabled"
|
||||
color="#b02a8f"
|
||||
@@ -166,6 +166,13 @@
|
||||
@change="toggleAlias(alias)"
|
||||
/>
|
||||
|
||||
<div
|
||||
class="btn-svg btn-send"
|
||||
@click="goToReverseAlias(alias)"
|
||||
>
|
||||
<font-awesome-icon icon="paper-plane" />
|
||||
</div>
|
||||
|
||||
<img
|
||||
src="/images/icon-dropdown.svg"
|
||||
v-if="alias"
|
||||
@@ -185,7 +192,7 @@
|
||||
{{ alias.note }}
|
||||
</div>
|
||||
|
||||
<div class="font-weight-lighter" style="font-size: 11px">
|
||||
<div class="font-weight-lighter" style="font-size: 11px;">
|
||||
{{ alias.nb_forward }} forwards, {{ alias.nb_reply }} replies,
|
||||
{{ alias.nb_block }} blocks.
|
||||
</div>
|
||||
@@ -206,7 +213,7 @@
|
||||
<div v-if="isFetchingAlias" class="text-secondary mx-auto text-center">
|
||||
<img
|
||||
src="/images/loading-three-dots.svg"
|
||||
style="width: 80px; margin: 20px"
|
||||
style="width: 80px; margin: 20px;"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -493,6 +500,12 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
// Reverse Alias
|
||||
goToReverseAlias(alias) {
|
||||
SLStorage.setTemporary("alias", alias);
|
||||
Navigation.navigateTo(Navigation.PATH.REVERSE_ALIAS, true);
|
||||
},
|
||||
|
||||
// Clipboard
|
||||
clipboardSuccessHandler({ value, event }) {
|
||||
Utils.showSuccess(value + " copied to clipboard");
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
<a
|
||||
@click="doNotAskRateAgain"
|
||||
class="text-secondary cursor"
|
||||
style="font-size: 0.7em"
|
||||
style="font-size: 0.7em;"
|
||||
>
|
||||
Do not ask again
|
||||
</a>
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
<template>
|
||||
<div class="content">
|
||||
<div class="p-2 container">
|
||||
<!-- Reverse-alias screen -->
|
||||
<div class="m-2 p-2" v-if="!createdReverseAlias">
|
||||
<p>
|
||||
Send emails from
|
||||
<span class="font-weight-bold">{{ alias.email }}</span>
|
||||
</p>
|
||||
<small>
|
||||
To send an email from your alias to a contact, you need to create a
|
||||
<b>reverse-alias</b>, a special email address. When you send an email
|
||||
to the reverse-alias, the email will be sent from your alias to the
|
||||
contact.<br /><br />
|
||||
This Youtube video can also quickly walk you through the steps:
|
||||
<a
|
||||
href="https://www.youtube.com/watch?v=VsypF-DBaow"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>How to send emails from an alias</a
|
||||
>
|
||||
</small>
|
||||
<br /><br />
|
||||
<label>
|
||||
Receiver:
|
||||
<font-awesome-icon
|
||||
v-b-tooltip.hover.top="'Where do you want to send the email?'"
|
||||
icon="question-circle"
|
||||
/>
|
||||
</label>
|
||||
<b-input
|
||||
v-model="receiverEmail"
|
||||
v-on:keyup.enter="createReverseAlias"
|
||||
placeholder="First Last <email@example.com>"
|
||||
:disabled="loading"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Created screen -->
|
||||
<div class="m-2 p-2" v-else>
|
||||
<p class="font-weight-bold">
|
||||
{{
|
||||
createdReverseAlias.existed
|
||||
? "You have created this reverse-alias before:"
|
||||
: "Reverse-alias is created:"
|
||||
}}
|
||||
</p>
|
||||
<p>
|
||||
<a
|
||||
v-clipboard="() => createdReverseAlias.reverse_alias"
|
||||
v-clipboard:success="clipboardSuccessHandler"
|
||||
v-clipboard:error="clipboardErrorHandler"
|
||||
v-b-tooltip.hover
|
||||
title="Click to Copy"
|
||||
class="cursor"
|
||||
>
|
||||
<span class="text-success">
|
||||
{{ createdReverseAlias.reverse_alias }}
|
||||
</span>
|
||||
</a>
|
||||
</p>
|
||||
<small>
|
||||
You can send email from one of these mailbox(es):
|
||||
<ul style="margin-bottom: 0;">
|
||||
<li v-for="mailbox in alias.mailboxes" v-bind:key="mailbox.id">
|
||||
{{ mailbox.email }}
|
||||
</li>
|
||||
</ul>
|
||||
The email will be forwarded to
|
||||
<b>{{ createdReverseAlias.contact }}</b
|
||||
>.<br />
|
||||
The receiver will see <b>{{ alias.email }}</b> as your email
|
||||
address.<br />
|
||||
</small>
|
||||
</div>
|
||||
|
||||
<div class="m-2 p-2">
|
||||
<button
|
||||
class="btn btn-sm btn-primary"
|
||||
@click="createReverseAlias"
|
||||
:disabled="loading || !receiverEmail"
|
||||
v-if="!createdReverseAlias"
|
||||
>
|
||||
Create a reverse-alias
|
||||
</button>
|
||||
|
||||
<button class="btn btn-sm btn-primary" @click="backToMainPage" v-else>
|
||||
<font-awesome-icon icon="arrow-left" />
|
||||
Back
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SLStorage from "../SLStorage";
|
||||
import Navigation from "../Navigation";
|
||||
import Utils from "../Utils";
|
||||
import { callAPI, API_ROUTE, API_ON_ERR } from "../APIService";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
alias: SLStorage.getTemporary("alias"),
|
||||
createdReverseAlias: null,
|
||||
loading: false,
|
||||
receiverEmail: "",
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// Clipboard
|
||||
clipboardSuccessHandler({ value, event }) {
|
||||
Utils.showSuccess(value + " copied to clipboard");
|
||||
},
|
||||
|
||||
clipboardErrorHandler({ value, event }) {
|
||||
console.error("error", value);
|
||||
},
|
||||
|
||||
// Create reverse-alias
|
||||
async createReverseAlias() {
|
||||
this.loading = true;
|
||||
const response = await callAPI(
|
||||
API_ROUTE.CREATE_REVERSE_ALIAS,
|
||||
{
|
||||
alias_id: this.alias.id,
|
||||
},
|
||||
{
|
||||
contact: this.receiverEmail,
|
||||
},
|
||||
API_ON_ERR.TOAST
|
||||
);
|
||||
this.createdReverseAlias = response ? response.data : null;
|
||||
this.loading = false;
|
||||
},
|
||||
|
||||
backToMainPage() {
|
||||
Navigation.navigateBack();
|
||||
},
|
||||
},
|
||||
computed: {},
|
||||
};
|
||||
</script>
|
||||
@@ -7,7 +7,7 @@
|
||||
</div>
|
||||
<div class="mb-2">The default API URL is https://app.simplelogin.io</div>
|
||||
|
||||
<div style="margin: auto">
|
||||
<div style="margin: auto;">
|
||||
<input
|
||||
v-model="apiUrl"
|
||||
v-on:keyup.enter="saveApiUrl"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div v-if="show" style="height: 400px">
|
||||
<div v-if="show" style="height: 400px;">
|
||||
<div class="splash overlay">
|
||||
<div class="overlay-content">
|
||||
<img class="logo" src="/images/horizontal-logo.svg" /><br />
|
||||
|
||||
+5
-1
@@ -26,6 +26,8 @@ import {
|
||||
faBug,
|
||||
faQuestionCircle,
|
||||
faCog,
|
||||
faPaperPlane,
|
||||
faArrowLeft,
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
|
||||
library.add(
|
||||
@@ -39,7 +41,9 @@ library.add(
|
||||
faSave,
|
||||
faBug,
|
||||
faQuestionCircle,
|
||||
faCog
|
||||
faCog,
|
||||
faPaperPlane,
|
||||
faArrowLeft
|
||||
);
|
||||
|
||||
global.browser = require("webextension-polyfill");
|
||||
|
||||
Reference in New Issue
Block a user