From 4c713bfce672743d4b0cbaa95e0a75a5388e010b Mon Sep 17 00:00:00 2001 From: Alicia Sykes Date: Thu, 14 Apr 2022 19:02:51 +0100 Subject: [PATCH] :sparkles: Adds Mullvad and IP blacklist check widgets --- docs/privacy.md | 4 + docs/widgets.md | 58 +++++++++ src/components/LinkItems/SubItemGroup.vue | 1 - src/components/Widgets/BlacklistCheck.vue | 137 ++++++++++++++++++++++ src/components/Widgets/MullvadStatus.vue | 111 ++++++++++++++++++ src/components/Widgets/WidgetBase.vue | 18 ++- src/mixins/WidgetMixin.js | 3 +- src/utils/MiscHelpers.js | 6 + src/utils/defaults.js | 2 + 9 files changed, 337 insertions(+), 3 deletions(-) create mode 100644 src/components/Widgets/BlacklistCheck.vue create mode 100644 src/components/Widgets/MullvadStatus.vue diff --git a/docs/privacy.md b/docs/privacy.md index 1df38c0d..22909bf1 100644 --- a/docs/privacy.md +++ b/docs/privacy.md @@ -109,6 +109,8 @@ Dashy supports [Widgets](/docs/widgets.md) for displaying dynamic content. Below - **[IP Address](/docs/widgets.md#public-ip)**: `https://ipapi.co/json` or `http://ip-api.com/json` - [IPGeoLocation Privacy Policy](https://ipgeolocation.io/privacy.html) - [IP-API Privacy Policy](https://ip-api.com/docs/legal) +- **[IP Blacklist](/docs/widgets.md#ip-blacklist)**: `https://api.blacklistchecker.com` + - [Blacklist Checker Privacy Policy](https://blacklistchecker.com/privacy) - **[Crypto Watch List](/docs/widgets.md#crypto-watch-list)** and **[Token Price History](/docs/widgets.md#crypto-token-price-history)**: `https://api.coingecko.com` - [CoinGecko Privacy Policy](https://www.coingecko.com/en/privacy) - **[Wallet Balance](/docs/widgets.md#wallet-balance)**: `https://api.blockcypher.com/` @@ -129,6 +131,8 @@ Dashy supports [Widgets](/docs/widgets.md) for displaying dynamic content. Below - No Policy Availible - **[News Headlines](/docs/widgets.md#news-headlines)**: `https://api.currentsapi.services` - [CurrentsAPI Privacy Policy](https://currentsapi.services/privacy) +- **[Mullvad Status](/docs/widgets.md#mullvad-status)**: `https://am.i.mullvad.net` + - [Mullvad Privacy Policy](https://mullvad.net/en/help/privacy-policy/) - **[TFL Status](/docs/widgets.md#tfl-status)**: `https://api.tfl.gov.uk` - [TFL Privacy Policy](https://tfl.gov.uk/corporate/privacy-and-cookies/) - **[Stock Price History](/docs/widgets.md#stock-price-history)**: `https://alphavantage.co` diff --git a/docs/widgets.md b/docs/widgets.md index 0919e8f0..bbfff1d8 100644 --- a/docs/widgets.md +++ b/docs/widgets.md @@ -14,10 +14,12 @@ Dashy has support for displaying dynamic content in the form of widgets. There a - [RSS Feed](#rss-feed) - [Image](#image) - [Public IP Address](#public-ip) + - [IP Blacklist Checker](#ip-blacklist) - [Crypto Watch List](#crypto-watch-list) - [Crypto Price History](#crypto-token-price-history) - [Crypto Wallet Balance](#wallet-balance) - [Code Stats](#code-stats) + - [Mullvad Status](#mullvad-status) - [Email Aliases (AnonAddy)](#anonaddy) - [Vulnerability Feed](#vulnerability-feed) - [Exchange Rates](#exchange-rates) @@ -285,6 +287,37 @@ Or --- +### IP Blacklist + +Notice certain web pages aren't loading? This widget quickly shows which blacklists your IP address (or host, or email) appears on, using data from [blacklistchecker.com](https://blacklistchecker.com/). + +

+ +##### Options + +**Field** | **Type** | **Required** | **Description** +--- | --- | --- | --- +**`ipAddress`** | `string` | _Optional_ | The IP to check. This can also be a domain/ host name or even an email address. If left blank, Dashy will use your current public IP address. +**`apiKey`** | `string` | Required | You can get your free API key from [blacklistchecker.com](https://blacklistchecker.com/keys) + +##### Example + +```yaml +- type: blacklist-check + options: + apiKey: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + ipAddress: 1.1.1.1 +``` + +##### Info +- **CORS**: 🟢 Enabled +- **Auth**: 🔴 Required +- **Price**: 🟠 Free Plan +- **Host**: Managed Instance Only +- **Privacy**: _See [BlacklistChecker Privacy Policy](https://blacklistchecker.com/privacy)_ + +--- + ### Crypto Watch List Keep track of price changes of your favorite crypto assets. Data is fetched from [CoinGecko](https://www.coingecko.com/). All fields are optional. @@ -433,6 +466,31 @@ Display your coding summary. [Code::Stats](https://codestats.net/) is a free and --- +### Mullvad Status + +Shows your Mullvad VPN connection status, as well as server info. Fetched from [am.i.mullvad.net](https://mullvad.net/en/check/) + +

+ +##### Options + +_No Options_ + +##### Example + +```yaml +- type: mullvad-status +``` + +##### Info +- **CORS**: 🟢 Enabled +- **Auth**: 🟢 Not Required +- **Price**: 🟢 Free +- **Host**: Managed +- **Privacy**: _See [Mullvad Privacy Policy](https://mullvad.net/en/help/privacy-policy/)_ + +--- + ### AnonAddy [AnonAddy](https://anonaddy.com/) is a free and open source mail forwarding service. Use it to protect your real email address, by using a different alias for each of your online accounts, and have all emails land in your normal inbox(es). Supports custom domains, email replies, PGP-encryption, multiple recipients and more diff --git a/src/components/LinkItems/SubItemGroup.vue b/src/components/LinkItems/SubItemGroup.vue index 71b78f62..2b4a2fbd 100644 --- a/src/components/LinkItems/SubItemGroup.vue +++ b/src/components/LinkItems/SubItemGroup.vue @@ -58,7 +58,6 @@ export default { border-radius: var(--curve-factor); text-decoration: none; transition: all 0.2s ease-in-out 0s; - color: var(--item-text-color); p.sub-item-group-title { margin: 0 auto; cursor: default; diff --git a/src/components/Widgets/BlacklistCheck.vue b/src/components/Widgets/BlacklistCheck.vue new file mode 100644 index 00000000..edf5e419 --- /dev/null +++ b/src/components/Widgets/BlacklistCheck.vue @@ -0,0 +1,137 @@ + + + + + diff --git a/src/components/Widgets/MullvadStatus.vue b/src/components/Widgets/MullvadStatus.vue new file mode 100644 index 00000000..9246e2a1 --- /dev/null +++ b/src/components/Widgets/MullvadStatus.vue @@ -0,0 +1,111 @@ + + + + + diff --git a/src/components/Widgets/WidgetBase.vue b/src/components/Widgets/WidgetBase.vue index bc406ddf..ac288d4f 100644 --- a/src/components/Widgets/WidgetBase.vue +++ b/src/components/Widgets/WidgetBase.vue @@ -34,6 +34,13 @@ @error="handleError" :ref="widgetRef" /> + + import('@/components/Widgets/AnonAddy.vue'), Apod: () => import('@/components/Widgets/Apod.vue'), + BlacklistCheck: () => import('@/components/Widgets/BlacklistCheck.vue'), Clock: () => import('@/components/Widgets/Clock.vue'), CodeStats: () => import('@/components/Widgets/CodeStats.vue'), CovidStats: () => import('@/components/Widgets/CovidStats.vue'), @@ -432,6 +447,7 @@ export default { IframeWidget: () => import('@/components/Widgets/IframeWidget.vue'), ImageWidget: () => import('@/components/Widgets/ImageWidget.vue'), Jokes: () => import('@/components/Widgets/Jokes.vue'), + MullvadStatus: () => import('@/components/Widgets/MullvadStatus.vue'), NdCpuHistory: () => import('@/components/Widgets/NdCpuHistory.vue'), NdLoadHistory: () => import('@/components/Widgets/NdLoadHistory.vue'), NdRamHistory: () => import('@/components/Widgets/NdRamHistory.vue'), @@ -476,7 +492,7 @@ export default { /* Returns users specified widget options, or empty object */ widgetOptions() { const options = this.widget.options || {}; - const timeout = this.widget.timeout || 2500; + const timeout = this.widget.timeout || null; const useProxy = this.appConfig.widgetsAlwaysUseProxy || !!this.widget.useProxy; const updateInterval = this.widget.updateInterval !== undefined ? this.widget.updateInterval : null; diff --git a/src/mixins/WidgetMixin.js b/src/mixins/WidgetMixin.js index 48e74c85..c0dd4a3a 100644 --- a/src/mixins/WidgetMixin.js +++ b/src/mixins/WidgetMixin.js @@ -20,6 +20,7 @@ const WidgetMixin = { overrideUpdateInterval: null, disableLoader: false, // Prevent ever showing the loader updater: null, // Stores interval + defaultTimeout: 1000, }), /* When component mounted, fetch initial data */ mounted() { @@ -106,7 +107,7 @@ const WidgetMixin = { const CustomHeaders = options || null; const headers = this.useProxy ? { 'Target-URL': endpoint, CustomHeaders: JSON.stringify(CustomHeaders) } : CustomHeaders; - const timeout = this.options.timeout || 500; + const timeout = this.options.timeout || this.defaultTimeout; const requestConfig = { method, url, headers, data, timeout, }; diff --git a/src/utils/MiscHelpers.js b/src/utils/MiscHelpers.js index cc26403e..35a54a03 100644 --- a/src/utils/MiscHelpers.js +++ b/src/utils/MiscHelpers.js @@ -46,6 +46,12 @@ export const timestampToDateTime = (timestamp) => { return `${timestampToDate(timestamp)} at ${timestampToTime(timestamp)}`; }; +/* Given a 2-letter country ISO code, return the countries name */ +export const getCountryFromIso = (iso) => { + const regionNames = new Intl.DisplayNames(['en'], { type: 'region' }); + return regionNames.of(iso); +}; + /* Given a 2-digit country code, return path to flag image from Flagpedia */ export const getCountryFlag = (countryCode, dimens) => { const protocol = 'https'; diff --git a/src/utils/defaults.js b/src/utils/defaults.js index 57a495c5..7ee4be7a 100644 --- a/src/utils/defaults.js +++ b/src/utils/defaults.js @@ -209,6 +209,7 @@ module.exports = { widgetApiEndpoints: { anonAddy: 'https://app.anonaddy.com', astronomyPictureOfTheDay: 'https://apodapi.herokuapp.com/api', + blacklistCheck: 'https://api.blacklistchecker.com/check', codeStats: 'https://codestats.net/', covidStats: 'https://disease.sh/v3/covid-19', cryptoPrices: 'https://api.coingecko.com/api/v3/coins/', @@ -223,6 +224,7 @@ module.exports = { holidays: 'https://kayaposoft.com/enrico/json/v2.0/?action=getHolidaysForDateRange', jokes: 'https://v2.jokeapi.dev/joke/', news: 'https://api.currentsapi.services/v1/latest-news', + mullvad: 'https://am.i.mullvad.net/json', publicIp: 'https://ipapi.co/json', publicIp2: 'https://api.ipgeolocation.io/ipgeo', publicIp3: 'http://ip-api.com/json',