Electrical-Forenics Home ray@RayFranco.com                       601.529.7473

   Updated February 11, 2026

   © Dr. Ray Franco, PhD, PE  :  2021-2026

Java Script Program to Render ICS Calendar Data

On the Internet, I found a application, JS_Calendar, based on Java Script that would render ICS Calendar-Data [2]. Unfortunately, I know almost nothing about java script, but eventually I got to work. All of the files and dependent libraries are at:

https://gitlab.nomagic.uk/popi/js_calendar_from_ics/-/tree/master>

I highly recommend you download them from the referenced location and read all the author's comments. The author's main reference is now dead. So just in case this site goes dead, you download them here.

The java script program, JS_Calendar, contains an index file and three directories with files in them.

To view the calendar with the vents. In your web browser, enter you website name followed by a back slash and your js_calendar directory:


https://website_name/js_calendar/
             

Unfortunately, if you copy the referenced js_calendar files to your website, all it will display is a blank calendar. This is because your web browser has a security feature called Cross-Open Resource Sharing (CORS).

To see the CORS error with Firefox:

Hamburger -> More tools -> Web Developement Tools -> Console Tab

We will fix the CORS errors in the next section.

Modifications to js/custom_display.js

Fortunately, all the modifications you must make to render you ics data is in one file, "js/custem_display.js". The ics files to import into the calendar are at the very top of js/custom_display.js. They are:


ics_sources = [
    {url:'https://sogo.nomagic.uk/SOGo/dav/public/contact/Calendar/3D08-5CC47000-1-5EA59B00.ics', title:'Nomagic Calendar', event_properties:{color: 'SeaGreen'}},
    {url:'https://nomagic.uk/calendars/gov.uk/events.ics', title: 'UK Bank Holidays in England and Wales', event_properties: {color: 'DodgerBlue'}},
    {url:'https://nomagic.uk/calendars/gouv.fr/events.ics', title: 'French Bank Holidays in Metropole', event_properties: {color: 'DeepPink'}}
]
             

These are the statements causing the CORS errors. When the java script request is made to download these files, your web browser is expecting a CORS allocation header giving it permission to do so. Either no header is being sent, or your website is not in the approved list (whitelist). To add your website to the approve list, you must be the owner of the website that contains the source.

However, there is a work-a-around. The download request can be made through an intermediate web server that makes the request on your behalf and adds the appropriate header. One such intermediate server is CORS-Anywhere. To use it append:

https://cors-anywhere.com/

to the beginning of your urls. This is the free version of cors-anywhere.com and there is a commercial version. For some reason, I had problems with the free version not showing all events when the number of urls is greater than 2. Since, I do read French, I commented out the last url.

Your modified ics source list, should look like:


ics_sources = [
    {url:'https://cors-anywhere.com/https://sogo.nomagic.uk/SOGo/dav/public/contact/Calendar/3D08-5CC47000-1-5EA59B00.ics', title:'Nomagic Calendar', event_properties:{color: 'SeaGreen'}},
    {url:'https://cors-anywhere.com/https://nomagic.uk/calendars/gov.uk/events.ics', title: 'UK Bank Holidays in England and Wales', event_properties: {color: 'DodgerBlue'}},
//    {url:'https://nomagic.uk/calendars/gouv.fr/events.ics', title: 'French Bank Holidays in Metropole', event_properties: {color: 'DeepPink'}}
]
             

Hopefully, this will run without any CORS errors.

If you still have CORS errors, you can download the calendar ics files, upload them to the js_calendar dirctory and change your ics sources to relative urls:


ics_sources = [
    {url:'3D08-5CC47000-1-5EA59B00.ics', title:'Nomagic Calendar', event_properties:{color: 'SeaGreen'}},
    {url:'events.ics', title: 'UK Bank Holidays in England and Wales', event_properties: {color: 'DodgerBlue'}}
]
             

A script for downloading the sources and uploading them to your website will be presented later.

Additional Changes to custom_display.js

To change the calendar view from British, with the first day of the week being Monday, to a US calendar, with the first day of the week being Sunday find (around line 60):

firstDay: '1',
local: 'uk',

and change to:

firstDay: '0',
local: 'us',

Changes to Index.html

These changes are optional, but recommended:

To view the calendar with a small screen such as a cell phone, add the following line under the header title:

<meta name="viewport" content="width=device-width, initial-scale=1.0">

Find the h1 header:

MyEntitiy - Our selected events feeds

This appears above the calendar, change to to something more appropriate, such as:

Wednesday Calendar

To evoke JS_Calenar and view your calendar go the calendar directory with the index file. It should automatically run index.html.

Cross-Origin Resource Sharing (CORS) Issues

I original had CORS errors. I am not exactly sure what the problem was, but part of it had to do with my website hosting. I have multiple websites with Host Gator. On one website everything worked, and on another I repeatedly received CORS errors. In addition, Firefox showed it as secure, and Apple Safari showed it as insecure. In the website inspector, it was reporting a CORS error to http and other places to https. I had to call Host Gator several times. They got the secure part fixed, but then I had to type the prefix "https://" into the address bar on my iPhone to get the calendar to show. Otherwise, it just went to my homepage. Eventually, Host Gator got the problems resolved.

I am sure about the accuracy of the two paragraphs below. They were written before the Host Gator fix. I currentlty do not have an htaccess file and everything is working fine. This may be because of Host Gator fixed the above.

You must have permission from the http(s) file server to access the files. This can only be done if you own the http(s) file server. That is, you must modify the http file server to allow you to access to its files. This is done on Apache by placing a ".htaccess" file in the directory were the resources you want access to are located [6]. Note, to get this to work, I had to use single quotation marks and not the double quotation marks in [7]. I am not sure this is still correct. Currently, I do not have an htaccess file and everything is working fine.

The second CORS issue was using a file for a URL. This causes a CORS error [4]. You must have an http server. You can set up a local http server using python [5]. I am not sure this is still correct.

On my iPhone, under Settings -> Safari, there is a radio button setting for Prevent Cross-Site Tracking. Is the related to CORS?

References

  1. Disable Browser Caching with Meta HTML Tags
  2. Disable browser caching with meta HTML tags
  3. How to use meta tags to turn off caching in all browsers?
  4. Fetch API: The Ultimate Guide to CORS and ‘no-cors’
  5. CORS Anywhere - Community-Hosted Instance
  6. Resolve CORS Errors Once and For All: Three Methods

Sharing Proton Calendar

Proton Calendar allows you to share your calendar-data with anyone by creating a public link to your calendar's data. Clicking on the link downloads a calendar.ics file (ics - internet calendaring and scheduling).

With Proton Calendar, you can create a link to a full view calendar.ics file or a limited view calendar.ics file. A limited view calendar.ics file show only when you are busy, without event details.

A calendar.ics file is just a plain text file that can be read by a text editor. It can be read by a human, but that is not its purpose. It is a standard for calendar data exchange. It can be read by and/or imported into a calendar program such as Google Calendar, Outlook Calendar, Apple Calendar, GNONE Calendar, etc.

This is fine, but what I wanted was a way to share a link to a calendar progam that would displayed my data. Fortunately, I found, on the Internet, a java script program that would do just that.

Proton Calendar does not have a way to mark events as busy or free. My work around for this is to have two calendars one for busy and another for free. The busy events are red, and the free events are green. When you create an event, you can select which calendar to place the event in. In addition, I also have a third calendars to keep up with my wife, which is brown.

Almost all calendar programs allow you to import more than one ics file. The java script program I found included this feature.

References

  1. Proton Calendar - How to share a calendar with anyone via a link

My Website - Public and Private Calendars

In my case, I have a public calendar and a private calendar. The public calendar is a limited view calendar that I give out to clients so they can see when I am busy.

The private view calendar is a full view calendar for my personal use. It displays three ics calendars: full_busy, full_free_and full_wife.

To kept my ics files seperate, I added an ics directory.

Bash Script to Download and Upload Proton ics Files

This bash script uses the curl (Client for Universal Resource Locator) command. You may need to install it:

sudo apt install curl

One script file downloads the four proton calendar (ics) files and uploads them to my website. Four curls statements download and rename the calendar files. By default, Proton uses thle same name, "calendar.ics" for every calendar file. The download files are stored in the /tmp directory.

Two curl statements upload the ics calendar files to my website. One curl statement for each calendar viewer.

To help your web browser see calendar updates, a copy of index.html with an updated date (via touch) is uploaded along with the ics files. In my case, the "index.html" file is the same for both calendar viewers. The copy of "index.html" is stored in "/var/tmp/". The contents of "/tmp/" is not persistance over a reboot.

Redacted Version of My Script File


#!/usr/bin/bash

#------------- Download the ics Files from Proton
curl -o /tmp/limited_view_busy.ics 'https://calendar.proton.me/api/calendar/v1/url/5PhjM74Z4mPxFrDZqlMtahH6C_Yz1WXT7h4h-Redacted-oncqR2v1QlWOPQrnw9KP3C4NYoINnLD3PUaHjtGQ==/calendar.ics?CacheKey=a0pJmg-Redacted-2WPxHw%3D%3D'

curl -o /tmp/full_view_busy.ics 'https://calendar.proton.me/api/calendar/v1/url/i5P4kgpeBOS4rfavSjRwPcbg2AKxOuAq7zFs-Redacted-5TcG0uj5AYE1eGONpGpPSFi7D2Vo3g_cbO8C2HtQ==/calendar.ics?CacheKey=Y6NsVx-Redacted-fnGBVg%3D%3D&PassphraseKey=5wN9fM5PIgog-Redacted-z-Ccl882gDbYwWEkvLk-Y%3D'

curl -o /tmp/full_view_free.ics 'https://calendar.proton.me/api/calendar/v1/url/9fzGuhmVpAh0uGj_10MY9UuzOJSpMgCRu6awA4jkxp54G9m4IwJmBkW-vWZfIsOlqEPe_xnl4oxi4n01oQwWRg==/calendar.ics?CacheKey=-1D5bb-Redacted-ZqWJMA%3D%3D&PassphraseKey=i__y5ZWhUD9S-Redacted-2PYIww8BVX9qGm9IvUzCw%3D'

curl -o /tmp/full_view_wife.ics 'https://calendar.proton.me/api/calendar/v1/url/Q8-k-5yQ4NQbOoaqDKiOdPkNQn08y3Upc4gYHiq6Dc-Redacted-dmzJp4Kf4bW59XX3pXGREZ2QcXiBeKXYchW2kBQ==/calendar.ics?CacheKey=PMBs1-Redacted-Ihp-rQw%3D%3D&PassphraseKey=R5z0f8ViCFMq-Redacted-g6EKdLsq5571OcoeJocyo%3D'


#---------- Upload the ics Files to My Website  -----
touch /tmp/index.html 
curl -u ray-Redacted-:4D-Redacted-x -T "{/tmp/limited_view_busy.ics,/tmp/index.html}" sftp://108.xxx.xxx.xxx/home/ray-Redacted.com/calendar/  
curl -u ray-Redacted-:4D-Redacted-x -T "{/tmp/full_view_busy.ics,/tmp/full_view_free.ics,/tmp/full_view_wife.ics,/tmp/index.html}" sftp://108.xxx.xxx.xxx/home/ray-Redacted.com/cal/ 
# curl notes: 
# 1. For multiple files, no spaces after the comma.
# 2. The sftp directory must end with a forward slash "/"

exit
              

Miscellaneous

According to Proton's website, if you share the calendar link with someone, they can import it into their calendar app and subscript to your calendar, which means they get updates. Is there some way to do this by code?

Be used to save all this code in a tar file on a NAS and/or on my website or on Proton's secure drive.

References

  1. Wikipedia ICalendar
  2. Display your ics calendar on your website
  3. CORS errors
  4. Reason: CORS request not HTTP
  5. How do you set up a local testing server?
  6. Reason: CORS header 'Access-Control-Allow-Origin' missing
  7. enable cors in .htaccess
  8. Copy as curl
  9. How to Use SFTP Command to Transfer Files
  10. How to run the sftp command with a password from Bash script?
  11. How to Create an ICS File: Easy Step-by-Step Guide

Custom Domain Name

References

  1. Custom Domains
  2. Review !!!!!
References
  1. Proton VPN - Leak Detector
  2. Proton VPN for Linux CLI release notes
  3. How to use the Proton VPN Linux CLI
  4. Proton VPN server list and locations
  5. 2025-05-18 - ProtonVPN Server List by Tim Tremblay
  6. Raspberry Pi Forum : Default keyring - becoming very annoying now
  7. Raspberry Pi Forum : Disable keychain request
  8. Raspberry Pi Forum : Chromium asking for default keyring
  9. Raspberry Pi Forum - Question: What is the 'default keyring' and How do I unlock it?
  10. The Best VPN Services of 2026
References
  1. Proton - How to use WireGuard on Linux
  2. https://www.wireguard.com/

Hardware Security Keys

As of 1/2/2026, Proton does not allow you to login to:

with a hardware security key such as Yubico.

You can however, log into https://account.proton.me/vpn.

Most of the links in the GUI app start with https://www.protonvpn.com. In addition, most of the links to download a configuration file for OpenVPN and WireGuard also start with https://www.protonvpn.com. However, you may be able to get to this page via https://account.proton.me/vpn.

Out of Date - Proton VPN

As of December 24, 2023 [3], the GUI Linux app for Proton VPN is not compatible with the Raspberry Pi OS.

You can use the Command Line Interface (cli) Linux app, but it is still on version 3, while the GUI is on version 4. The current cli Linux app does not have an auto-connect feature, while the GUI version does offer auto-connect.

You have manually login:

protonvpn-cli login your_user_name

You then have to connect:

protonvpn-cli connect or just c

A console window will pop up, and you have to select the server country. Then, you must wait for almost one minute in the US, for the app to pole all the severs in the country to determine their availability and load. Some of the servers can stream videos and others cannot. After you select a sever, it will prompt you on whether to use UDP or TCP. Finally, it will connect and work as it should.

To disconnect:

protonvpn-cli disconnect or just d

To logout:

protonvpn-cli logout

To get help:

protonvpn-cli --help or -h

Proton's website says "Our new (v4) Linux doesn’t yet support a command line tool"[4]. Hopefully, this feature will be coming. According to a response in December 2023, at protonmail.uservoice.com, the cli version is planned.

References

  1. Wikipedia ICalendar
  2. Display your ics calendar on your website
  3. CORS errors
  4. Reason: CORS request not HTTP
  5. How do you set up a local testing server?
  6. Reason: CORS header 'Access-Control-Allow-Origin' missing
  7. enable cors in .htaccess
  8. Copy as curl
  9. How to Use SFTP Command to Transfer Files
  10. How to run the sftp command with a password from Bash script?
  11. Scheduling Cron Jobs with Crontab
  12. How to Automate Tasks with cron Jobs in Linux
  13. If user didn't login, will cron job be executed?
  14. how to set crontab PATH variable
  15. Best VPNs for Raspberry Pi
  16. How to use Proton VPN on Linux