Complete ICS / iCal / iCalendar parser / expander

I had trouble finding a iCalendar parser that lets me get the actual events as shown in my google calendar. This means automatically handling EXDATE (excluded recursive occurrences), RRULE and recurring events overridden by RECURRENCE-ID. Also timezones need to be supported.

So I made a library that builds on ical.js.


Reverse engineering DNB VIPPS API by injecting Charles cert as pinned SSL certificate


The VIPPS app is using API SSL certificate pinning to prevent MITM attacks, and the pinned certificate(s) is stored in the APK itself, so it can easily be replaced by our own generated Charles certificate. This allows sniffing the data going from the app to VIPPS servers.


First download the APK from somewhere (google it)

Debuild APK
apktool d no.dnb.vipps-1.6.5.apk

Export Charles MITM SSL certificate by going to Help -> SSL Proxying -> Save Charles Root Certificate

Inject Charles certificate into app
cp charles-ssl-proxying-certificate.cer no.dnb.vipps-1.6.5.apk.out/res/raw/prod_priority_1.cer

Put APK back together
apktool b no.dnb.vipps-1.6.5.apk.out -o vipps-modified.apk

Generate debug keystore for signing the new app
echo y | keytool -genkey -v -keystore debug.keystore -storepass android -alias androiddebugkey -keypass android -keyalg RSA -keysize 2048 -validity 10000 -dname "cn=Mark Jones, ou=JavaSoft, o=Sun, c=US"

Sign app with keystore
apksigner sign --ks debug.keystore --out vipps-modified-signed.apk vipps-modified.apk

Enter pw android

Verify signing
apksigner verify vipps-modified-signed.apk

Install new APK to device
adb install vipps-modified-signed.apk

Now just start Charles with SSL proxying enabled and set Charles (your computer’s IP) as the proxy under WIFI settings on the Android device.

Going further – decompiling

brew install dex2jar

d2j-dex2jar -f -o vipps.jar no.dnb.vipps-1.6.5.apk

Use one of the following GUI tools for decompiling and looking at the code:

None of them are perfect, and some code seems to fail decompiling in both.


AWS Cogntio: Prevent email from being sent when email changed

When calling adminUpdateUserAttributes to change email address of a user in Cognito User Pools, the attribute email_verified will be set to false, and an email will be sent out to the user with a verification code.
If you want to disable this logic and prevent the email from being sent out, include email_verified=true in the update attributes request, like so:

 "UserAttributes": [
   "Name": "email",
   "Value": ""
   "Name": "email_verified",
   "Value": "true"


I needed a tool for quickly trimming recorded videos, so I built my first Electron app, check it out:

Download links:

It is a cross platform simple video editor for lossless trimming / cutting of videos using ffmpeg and Electron. Great for rough processing of large video files taken from a video camera, drone, etc. Lets you quickly get rid of the useless parts. It doesn’t do any decoding / encoding and is therefore very fast and has no quality loss. Also allows for taking JPEG snapshots of the video at the selected time.

Extract GPS data from “Tracker” iOS app to GPS

Quick script for extracting gps data from the “Tracker” GPS app

First export data from app com.eofster.tracker using something like iPhone Backup Extractor (

npm install csvtojson
npm install gps-to-gpx

cd 'com.eofster.tracker/Library/Application Support/com.eofster.tracker'
sqlite3 -header -csv Tracker.sqlite "select * from ZTRACKPOINT order by ZTIMESTAMP;" > out.csv


node . > out.gpx

dynamodump – backup DynamoDB tables with structure

I created a Node.js CLI for exporting & importing schema and data from DynamoDB tables. I didn’t find any other node tools for dumping table schema (structure, indexes etc), they all just dump data.

How to email Norwegian / Hvordan kontakte Norwegian på epost

In case you had a hard time finding out how to reach the airline Norwegian by email/contact form, because I sure did. However they do have a contact page at a cryptic URL:

And their support email:

DJI Phantom 3 parallel battery charging in a car with iMax B6

I bought a “Multi Battery Parallel Charging Board For DJI phantom3” on ebay, and I soldered on a deans female connector for connecting it to my iMax B6 charger.


Since the Phantom 3 battery is intelligent and has its charging circuitry in the battery itself, the iMax will just work as a voltage booster with an output of 18V. This is 0.5V more than the DJI charger provides but it seems to work. So anything that can output >3A ~17.5V should be able to replace the iMax.


  1. Connect iMax input to car cigarette connector
  2. Connect iMax output to the multi-charging board.
  3. Connect the Phantom battery to the board
  4. Choose Pb charge, 5.0A, 18.0V (9P)
  5. Turn the battery on right before long-pressing start on the iMax (by using the
  6. short-then-long-press sequence on the Phantom battery.)
  7. When the battery is full it will say CONNECTION BREAK, but this is because the intelligent battery circuit will disconnect itself when fully charged.

In the next version i will be using a cheap boost converter from ebay, like this:


Oslo bysykkel kart / Oslo city bike live map

Oslo city bike is a great system and I often jump on a bike. But sometimes I wanted to be able to quickly check the status of the bicycles in my neighbourhood from my computer without having to log in to the app on my phone. Oslobysykkel doesn’t have this information in their map, so I made a public map with live updated availability of the bikes.

Check it out 🚲

Update: I see that just updated their map to include availability at the very same time 😂

1W burning blue laser with driver for <$36


* M140 laser diode (<$30 on ebay)
* Aixiz module (<$3 on ebay)
* LED driver supplying 1-1.25A. I used this one (<$3):

1. Unscrew line/cross filter in front of lens on Aixiz module, if present.
2. Remove existing red laser diode from Aixiz module by using a vise, some cloth and screws for pushing it out.
3. Carefully insert new m140 laser diode using a vise and some cloth and screws for pushing it in by its base.
4. Google “m140 pinout” to figure out the pins
5. Solder the outputs from the LED driver module to the m140 + and – pins.
5. Connect some voltage source to the module’s input, i used a 3S LiPo.

Important notes:
* Use laser safety goggles for the correct wavelength.
* Laser diodes are very sensitive to voltage transients and static electricity. This means that when handling and soldering the diode, keep the two pins shorted until it is completely soldered to the driver circuit, then disconnect the short. I used some tiny connector probes that clamped on to each pin.
* Keep the soldering quick. They don’t want high temperatures. Preferable mount the diode in a module before soldering (to ensure heatsinking)

« Older posts

© 2017 Mikael Finstad

Theme by Anders NorenUp ↑