RSSAmplifier

Blog

Adriaan's blog

blog.adriaan.ioRSS feed ↗59 posts

Latest posts

How to set up Chatwoot with Migadu

If you’re self-hosting Chatwoot and want to send emails using Migadu , here’s a quick guide. This helps you send out system emails, like invite emails, password recovery emails, etc. To use it for email conversations, you can set up an inbox in Chatwoot. No need for these environment variables. Update your .env file with the following SMTP settings. Replace all instances of example.com with your…

How to block last history item in terminal on macOS

Sometimes I enter something in my terminal that could be painful when compromised. To fix that, GPT, the internet, and I created a function to delete the last item in my history. Add this function to your .zshrc file: function forget () { # Set the target line to the last command in history local target_line = -1 # Prevent the last history line from being saved local HISTORY_IGNORE = " ${ (b) $(…

How to block traffic from a specific IP address with Docker enabled

Using Docker can sometimes lead to an issue where all traffic routes through Docker via iptables , bypassing other layers such as NGINX . To mitigate this, you’ll need to introduce a specific rule in iptables targeting the DOCKER-USER chain. Suppose you aim to block all incoming traffic from the IP address 1.2.3.4 . Here’s how you can achieve that: 1. View Current iptables Rules Begin by checking…

Remove and redirect trailing slashes from URLs in Nuxt 3

Create this file in your middleware folder called middleware/trailing-slash.global.js : export default function ({ path , query , hash }) { if ( path === " / " || ! path . endsWith ( " / " )) return ; const nextPath = path . replace ( / \/ +$/ , "" ) || " / " ; const nextRoute = { path : nextPath , query , hash }; // 308 Permanent Redirect return navigateTo ( nextRoute , { redirectCode : 308 }); }

A simple loading animation component in Vue.js

What to do if you want a simple SVG loading circle. You can do it with a div in HTML, but the positioning of the element is always a bit annoying. That’s why I created a simple component in Vue that works easier. This is how the component loader (only the loading circle) looks like: I needed rounded corners on the circle ends, so I’m stuck with a svg stroke. It’s not the best to work with, but…

Valdiate email addresses with MX records in Node.js

This might help others in their search for some email validator based on MX DNS records . In Node.js it’s important to specify the dnsServers , because otherwise it will only check the local resolver. In my case this was causing issues. const { Resolver } = require ( " dns " ). promises ; const isValidRegexEmail = ( email ) => / [^ @ \s] +@ [^ @ \s] + \.[^ @ \s] +/ . test ( email ) && ! / \s / .…

Paste keystrokes automatically with Apple Automator

Want to paste a text into some place? Create an AppleScript with this code: on run { input , parameters } delay 5 tell application "System Events" repeat with charOfInput in ( characters of ( input as text )) set asciiValue to ASCII number of charOfInput -- Check if ASCII value is in the range of uppercase letters (65-90) if asciiValue ≥ 65 and asciiValue ≤ 90 then key down shift keystroke…

Promise with a timeout

Sometimes you don’t want to wait for a JavaScript promise to resolve if it takes too long, just like this sentence. The Promise.race is a perfect solution for this. This method returns a promise that fulfills or rejects as soon as one of the promises in an iterable fulfills or rejects, with the value or reason from that promise. const timeoutPromise = async ({ promise , timeout = 1000 ,…

Turn off Wi-Fi when macOS goes to sleep

When I am on a network that’s paid by the hour you want to disable your Wi-Fi when you are not using your mac. To do this I listen for when the mac goes to sleep and disable the Wi-Fi. Install sleepwatcher with homebrew: brew install sleepwatcher I have my scripts living in ~/Developer/scripts (create that folder with mkdir -p ~/Developer/scripts ) Create a script at…

Convert URL searchParams to plain JS Object

In Node.js the url.parse API is deprecated. But one of the great things was getting an plain JavaScript object from your query params: const { query } = url . parse ( " https://example.com/?search=term&page=1 " , true ); console . log ( query ); // [Object: null prototype] { search: 'term', page: '1' } Want to know what [Object: null prototype] is? Check this StackOverflow answer . Fortunately…

Vue 2: this.$refs is undefined with v-if

this.$refs is undefined when the element with the ref attribute is not visable at the moment you use the this.$refs object. This costs me some time to figure out. Let’s say you have an app that looks like this: <div id= "app" > <p><button @ click= "openBox" > Toggle </button></p> <div v-if= "open" > <input type= "text" ref= "inputField" /> </div> </div> < script > var app = new Vue ({ el : " #app…

Install Docker on Raspberry Pi 4 with Ubuntu 20.04

In the documentation of Docker it says to install the OS version with lsb_release -cs . For me this returned focal , but Docker does not have the release files for that version it seems. I got errors like E: Package 'docker-ce' has no installation candidate . Just change lsb_release -cs to bionic (for armhf ): sudo add-apt-repository \ "deb [arch=armhf] https://download.docker.com/linux/ubuntu \…

Make a JavaScript array with objects unique by its (nested) key

Comparing an array with objects in JavaScript can be a bit annoying. Let’s say you have an array with objects like this: const array = [ { name : " Adriaan " , address : { city : " Amsterdam " } }, { name : " Adriaan " , address : { city : " Chiang Mai " } }, { name : " Maria " , address : { city : " Nazareth " } }, { name : " Tim " , address : { city : " Amsterdam " } } ] You can use this little…

How to copy Let's Encrypt account including all certificates to a new server

You can copy the entire dir /etc/letsencrypt/ and restore it on your new server. Make sure to be logged in to your old server Run cd ~/ && sudo tar zpcvf 2020-11-10-letsencrypt-backup.tar.gz /etc/letsencrypt/ Copy this file ( 2020-11-10-letsencrypt-backup.tar.gz ) from the home directory in your old server to your new server. In short run cd ~/ && scp 2020-11-10-letsencrypt-backup.tar.gz…

Running Ubuntu in VirtualBox on macOS fails because rf kill switch

When you installation crashed on load/save rf kill switch status /dev/rfkill watch : You can fix this by running in your macOS terminal: sudo virtualbox Keep the terminal open and you can run your Ubuntu version in VirtualBox!

Allow (whitelist) domains with Algo VPN in DNSCrypt Proxy

DNSCrypt Proxy is one of the tools build into the Algo VPN ansible scripts . It’s great for blocking ads and trackers. I run a privacy friendly analytics tool called Simple Analytics. For developing my tool I need to make sure it’s never blocked in my VPN. I use the term whitelist because it’s being used within DNSCrypt and because people search with this keyword. I would prefer to call it…

Open external links in a new tab in JavaScript

When you have links on your page but you want to open them in a new tab (when visitors are navigating to another website). You can use this function: window . addEventListener ( " DOMContentLoaded " , function externalLinks () { var anchors = document . getElementsByTagName ( " a " ); for ( var i = 0 ; i < anchors . length ; i ++ ) { if ( anchors [ i ]. hostname !== window . location . hostname )…

Install Ubuntu Server 18.04.4 on encrypted disks with RAID 1, GRUB, and legacy BIOS

In this guide I explain how to install Ubuntu Server 18.04.4 on a (bare metal) server with two disk in RAID 1 mode. You will loose all data on your server if you follow this guide. I will use a full disk encryption with dm-crypt . My hosting provider does not support EUFI so I used legacy BIOS to run the server. This means you can’t use disks larger than x TB. We will not use LUKS as it’s another…

Make array with objects unique on multiple keys in javascript

Let’s say you have an array with objects: const browsers = [ { os : " OS X " , os_version : " Catalina " , browser : " chrome " , browser_version : " 30.0 " }, { os : " Windows " , os_version : " 7 " , browser : " chrome " , browser_version : " 40.0 " }, { os : " Windows " , os_version : " 7 " , browser : " chrome " , browser_version : " 50.0 " } ]; Let’s assume you only want to have browsers with…

Replacement for optional chaining for nested JS objects

Sometimes you have to get a variable from a nested object like this const customer = { sources : { data : [{ type : ' card ' , last4 : ' 1234 ' }] } } If you want to get the value 1234 , you could do this: const { last4 } = customer . sources . data [ 0 ] But if you don’t know if the whole object will be there (like with this Stripe response), you’ll need to check for every variable: let last4 if…

Disable Firefox Account / Sync

Firefox has a feature where they want you to register for. It’s Firefox Account. Sometimes called Firefox Sync. It’s something I don’t like to do, it’s a browser and it doesn’t need to know who I am. That’s why I disabled the Firefox Account feature including the button and tab in settings. Here is how: Open about:config and search for identity.fxaccounts.enabled or copy paste the following url…

Run a simple server on your Mac for your static files

Python3 has a nice way of starting a server: python3 -m http.server 8080 . This works super nice, but I always forget how to type this command. So I created a little function in ~/.bash_profile on my Mac: server () { local port = ${ 1 :- 8080 } if [[ $port -eq 80 ]] ; then sudo python3 -m http.server $port else python3 -m http.server $port fi } Now I can type server 80 or server to run a simple…

Links in iOS Safari WebApp keeps opening in a new tab

When you use the <meta name="apple-mobile-web-app-capable" content="yes"> tag in your HTML the links in your app with open in a new tab in Safari. This is something you usually don’t want. Put this as the first script in your <head> : if (( ' standalone ' in navigator ) && navigator . standalone ) { document . addEventListener ( ' click ' , function ( e ) { var curnode = e . target while ( ! ( /^…

Bimes: Generate random rememberable words in Node.js

At my last job we needed a word or string which our customers could remember. It also should be generated automatically. While drawing our ideas on the drawing board we came up with a solution that seemed to work. Why not use a consonant followed by a vowel and repeat this for n times. Af course you need a blacklist of words when generating automatically, especially when you can create actual…

Send notifications from Stripe to your own Telegram via Node.js

In this blog post I will show you how you can get Telegram notifications from Stripe events. I did set it up for when somebody is a new user (first payment) and for when I get a payment. I use Node.js without any framework. Stripe does not send it’s user email address with the webhook payload so I grab that from my own PostgreSQL database. I assume you have the following environment variables:…

Log output of your cronjobs to syslog in Ubuntu

When I setup crontab for a script I want to have all logging in syslog. This way I can see all live output of the script with a single command tail -n 100 -f /var/log/syslog . If I have this crontab */10 * * * * /home/user/do-something.sh ( crontab -l ) I would see this in the logs: Dec 29 12:00:00 server CRON[1011]: (user) CMD (/home/user/do-something.sh) Dec 29 12:00:00 server CRON[1009]: (CRON)…

One NGINX error page to rule them all

When I setup an NGINX server I have to setup custom error pages for every error. I want to show the error message on the page and not have a genenic “Something is wrong” error page. If customers complain about an error page it’s nice if they can communicate you the error code or message. Before & after NGINX error page config First of all you need to create an error_page in your http , server , or…

Turn on automatic apt-get updates and upgrades

Often times when I login to a VPS I get this a message like this: 32 packages can be updated. 11 updates are security updates. I don’t want to type sudo apt-get update and sudo apt-get upgrade all the time. But sudo apt-get update is interactive by default so you have to hit enter or type y . So I did a little reseach on how to put apt-get in noninteractive mode and it’s quite simple. Just append…

End to the endless if's to get a JavaScript value in (nested) objects

UPDATE : I created a better blog post without the use of eval Sometimes you have to get a variable from a nested object like this const customer = { sources : { data : [{ type : ' card ' , last4 : ' 1234 ' }] } } If you want to get the value 1234 , you could do this: const { last4 } = customer . sources . data [ 0 ] But if you don’t know if the whole object will be there (like with this Stripe…

Log CRON to syslog on Ubuntu

I got this message in by logs No MTA installed, discarding output This is because CRON (crontab) is sending it’s data to a mail client. Ubuntu does not come with a mail client, so it throws this error. But I don’t want mail for error logging, so I looked online and found that you can use logger and pipe your CRON command to it. I use a date function, so make sure to escape the % ’s. 02 4 * * *…

Submit Event Listener Does Not Work

When you want to submit a form programmatically the event submit does not get triggered. Here is how you can still trigger the submit event. I use this when I have another element than a submit button in a form. Let’s say we have this form: <form> <input name= "email" type= "email" placeholder= "Enter your email" > <img class= "submit-image" src= "..." alt= "Submit" > </form> I would love to…

Merge conflict in package-lock.json

We probably have all been here $ git pull origin develop remote: Counting objects: 14, done . remote: Total 14 ( delta 6 ) , reused 6 ( delta 6 ) , pack-reused 8 Unpacking objects: 100% ( 14/14 ) , done . From github.com:adriaandotcom/feature/something-really-awesome * branch develop -> FETCH_HEAD 41a55e3..575f291 develop -> origin/develop Auto-merging package.json Auto-merging package-lock.json…

What I do when I setup my new Mac

When I install my new Mac I do a few things to set it to my needs. Maybe you like those apps and settings and can use it as well. If I need more essentials, hit my up on X . Install Firefox for the dev tools (I tried Safari, but no) Visual Studio Code for editing text Paste for managing your clipboard Brew for packages nvm for Node versions Terminal Inconsolata font Setup git Add this to the…

How To Adjust Brightness In Final Cut Pro

Apple added a great feature in Final Cut Pro X 10.4 called advanced color grading . With this feature you have color wheels where you can color grade the image in a similar way as in Adobe Premiere Pro. It also supports brightness and seturation levels. Go to Color Inspector in the right side bar. If it does not show up there, go to Window > Go To > Color Inspector . As a default it gives you the…

Make Async Await Work In Promises

I have some issues with getting async and await working inside of Promise ’s. When using this code: function returnSomething ( name ) { return new Promise (( resolve , reject ) => { const somethingElse = await returnSomethingElse (); return resolve ( somethingElse ); }); } I got this error /app/app.js:63 const something = await returnSomethingElse(); ^^^^^^^^^^^^^^^^^^^ SyntaxError: Unexpected…

Use Ember Get For Nested Objects

Sometimes you have to get a variable from a nested object like this const toys = { muppets : { ernie : { head : ' wide ' } } } If you are not sure if the complete object exist, you will have to do something like this: const ernieHead = ( toys && toys . muppets && toys . muppets . ernie && toys . muppets . ernie . head ) ? toys . muppets . ernie . head : undefined ; // Do more with ernieHead...…

macOS Sierra Broke My Git

One morning I was running git status . I got this ugly error message in my terminal: xcrun: error: invalid active developer path ( /Library/Developer/CommandLineTools ) , missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun This is of course not very workable. I installed macOS Sierra last night. After reading some post s on disableing System Integrity Protection I found a…

The New Details And Summary Tag

With this details -tag you can create foldable / collapsible content: <details> <summary> This is a summary of the collapsible content </summary> And this is the very long content.. It can have <strong> HTML </strong> -tags in it as well! </details> This is the content when it is collapsed: And this is the content when it is not collapsed: It’s handy for hiding logs in GitHub issues but you can…

How Clearfix Can Demolish Flexbox

This cost me some minutes of my life. I was using display: flex on a div in my code with justify-content: space-between : <div> <p> Small text </p> <p><input type= "submit" value= "Do something" class= "button" ></p> </div> But it aligned like this: The scss looked not so strange, so I put everything in a jsfiddle to figure it out, but it showed correctly. div { @include clearfix ; width : 300px ;…

Check If Elements Are In Viewport In Vanilla Javascript

With CSS you can do a lot of cool stuff like transform and transition . But you will still need JavaScript to add and remove classes to elements. In the code example you will see how to add classes to elements which are in the current viewport. It will not cover how to remove them later. Let’s say you have some sections on your webpage and you want to show them with a nice transition when they…

Exclude Folders In Sublime Text Search

When you use the Find in folder -function of Sublime Text, you probaly hate the fact it is also searching in your node_modules folder. There is a nice feature in Sublime Text where you can specify which folders to exclude from your search. Right-click on a folder and select Find in folder… (there will be input fields shown on the bottom), you will see the Where -input field. If is probably already…

Different Files Per Environment In Ember

Maybe you want to have a logo with the same url showing something different on production and staging. Or you want to have different robots.txt files because you don’t want to give robots permision on you non-production environment (like staging or acceptance). In Ember.js you can edit the tree like this: // ember-cli-build.js ' use strict ' ; const EmberApp = require ( '…

How To Push Without Set Upstream In Git

Tiered of typing git branch --set-upstream awesome-branch origin/awesome-branch ? Change your git setting to use the current branch name: git config --global push.default current And you can just use git push Thanks to zamith on stackoverflow.com .

Transfer Files From The Command Line

A cool new service from The Netherlands is launched. It is called https://transfer.sh . With a simple command from the terminal you can send a file to their server. You will get a short url back and you can share it because it is online available. curl --upload-file ./hello.txt https://transfer.sh/hello.txt It will return you the url where it is hosted, for example…

Sublime Text 3 pretty JSON

Install this packages via CMD + SHIFT + P > Install package > Search for Pretty JSON and install . And then turn ugly json via CMD + CTRL + J (OSX) CTRL + ALT + J (Windows/Linux) in pretty JSON! This package is written by Nikolajus Krauklis and available on GitHub .

Setup Git shortcuts (aliases)

I like to type short commands for commands I use very often. If you use Git, then you probably use that command a lot. I have some shortcuts setup for git like this: git co for git checkout git st for git status (not stash) git ci for git commit On Mac you can edit your .gitconfig file by typing nano ~/.gitconfig and add the following: [alias] co = checkout ci = commit st = status br = branch hist…

Replace all in JavaScript

The JavaScript .replace() function will only replace the first instance if you use just two strings like this: var text = " This is the blog of Adriaan, the worst blog in the universe " ; text . replace ( " blog " , " life " ); // 'This is the life of Adriaan, the worst blog in the universe' So to replace all occurrences of blog you can use: text . replace ( /blog/g , " life " ); But that is 30%…

Front end developers and designers, increase your contrast

If you have a shiny Mac as a front end developer or designer you will see your webpages in the most beautiful way. Everyone with such a nice display will see your website in the best possible way. But there are others. People with less great screens, people who use a display with a VGA-cable or bad splitter. Those people will see your website not is the most beautiful way. So before you push your…

Run cronjobs with dokku PaaS

I have a crawler running for watiseropderadio.nl and I got some problems with setting up the crontabs for it. I have a node application with a simple node webserver and some other scripts which are runnable via npm run ... . I deployed the app to a dokku server and it was running. Next I wanted to test the run -command of dukku: ssh -t dokku@xxx.xxx.xxx.xxx -- run crawler npm run npm_script_name…

Disable mouse gestures in Google Chrome on Mac

If you hate this arrow as much as I do, then you want to disable it right away! Go to your terminal and run these commands: defaults write com.google.Chrome AppleEnableSwipeNavigateWithScrolls -bool true defaults write com.google.Chrome AppleEnableMouseSwipeNavigateWithScrolls -bool true Then restart your Chrome and be happy. Before Mavericks Before Mavericks this command was enought, but it does…