Table of Contents

Customizing your Customer Portal

Mitchell Paul-Soumis Updated by Mitchell Paul-Soumis

Read Time: 6 mins

While Sonar provides a pre-built Customer Portal that can be tied to your instance and used to provide more control to your customers, we don't want to limit your creativity, branding, or control how your customers access their information. The Sonar Customer Portal code repository is available on https://github.com/SonarSoftwareInc/customer_portal, and you're welcome to fork or clone this repository in order to modify the underlying code to suit your needs.

Don't modify the files inside the existing Docker Container without redirecting the GitHub link, as updates will overwrite all changes during an update

Cloning the Repository

For cloning the repository to make minor changes, you can follow the guide below:

  1. git clone the portal onto a droplet
droplet# git clone github.com/sonarsoftwareinc/customer_portal
  1. Modify the Docker Compose file:
droplet# nano ./customer_portal/docker-compose.yml
  1. Change image name in Docker Compose file from

image: "sonarsoftware/customerportal:stable"

to a unique name. In this example, we'll be changing it to "image: customized:stable"

  1. Remove the lines containing "watchtower"
Currently, this occupies line 40-45, however, it's important to note these line numbers may change as updates are made to the portal.

40 watchtower:

41 image: v2tec/watchtower

42 restart: always

43 volumes:

44 - /var/run/docker.sock:/var/run/docker.sock

45 command: sonar-customerportal

  1. Save the modified "docker-compose.yml"

If you've already run the Customer Portal container before making these changes, you'll need to run the following commands:

  1. Take the docker container down and remove any leftover elements
docker-compose down --remove-orphans
  1. Bring the docker container back up with the new "docker-compose.yml" file we've just created
docker-compose up --build -d

Customization Example: Remove the ability to delete a payment method

  1. Enter the source file to the specific location housing billing parameters:
droplet#nano ./customer_portal/resources/views/pages/billing/index.blade.php
  1. Remove lines 321 - 326 & 391 - 396 (inclusive)
  2. Save "Index.blade.php"

Customization Example: Disable the Auto-Pay toggle

Because the EU and Australia mandate that explicit consent be given by the customer in order to have Auto-Pay enabled, this customization should NOT be performed if you have customers in those locations
  1. Enter the source file to the specific location housing billing parameters:
droplet#nano ./customer_portal/resources/views/pages/billing/index.blade.php
  1.  Remove lines 308 - 320, which contains the Auto-pay toggle code:
1 @if($paymentMethod->auto == 1)
2 {!! Form::open(['action' => ["BillingController@toggleAutoPay",$paymentMethod->id],'id' => 'deletePaymentMethodForm', 'method' => 'patch']) !!}
3 <button class="dropdown-item btn btn-sm btn-danger" onClick="submit(); this.disabled=true;this.innerHTML='<i class="fe fe-loader mt-2 mr-2 "></i> {{utrans("billing.disabling")}}'">
4 <i class="fe fe-minus-circle mr-2"></i> {{utrans("billing.disableAuto")}}
5 </button>
6 {!! Form::close() !!}
7 @else
8 {!! Form::open(['action' => ["BillingController@toggleAutoPay",$paymentMethod->id],'id' => 'deletePaymentMethodForm', 'method' => 'patch']) !!}
9 <button class="dropdown-item btn btn-sm btn-primary" onClick="submit(); this.disabled=true;this.innerHTML='<i class="fe fe-loader mt-2 mr-2"></i> {{utrans("billing.enabling")}}'">
10 <i class="fe fe-check-circle mr-2"></i> {{utrans("billing.enableAuto")}}
11 </button>
12 {!! Form::close() !!}
13 @endif
  1. Save "Index.blade.php"
  2. Modify Auto-pay on new credit card payments by entering the file which controls the logic for adding new cards:\
droplet#nano ./customer_portal/resources/views/pages/billing/add_card.blade.php
  1. Replace the following lines:
<div class="col mt-1">
{!! Form::checkbox("auto",1,false,['id' => 'auto', 'class' => 'custom-control-input']) !!}
<label class="custom-control-label" for="auto"></label>

with:

<input type="hidden" id="auto" class="custom-control-input" name="auto" value="1">
Using this method, a user could disable this by entering the developer tools and setting "value=0"
  1. Because the above lines remove the toggle on the "Add Credit Card" page, we also want to remove the visible tooltip that contains the "Automatically charge this card for all future invoices" text:
<div class="col mt-1">
<small class="text-muted">
{{utrans("billing.saveAsAutoPayMethod")}}
</small>
</div>

Customization Example: Using alternative SSL certificates

Sonar provides Let's Encrypt certificates for the portal domain you provide, and will automatically renew the certificate before its expiry, however, if you'd like to supply your own certificate, follow the steps below
  1. After your installation has completed, stop Certbot from running:
    docker-compose stop certbot
  2. Modify the Docker compose file:
    droplet# nano ./customer_portal/docker-compose.yml
  3. Comment out the entire section containing Certbot instructions. It should appear similar to the below:
      # certbot:
    # image: certbot/certbot
    # restart: always
    # entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
    # volumes:
    # - ./data/certbot/conf:/etc/letsencrypt
    # - ./data/certbot/www:/var/www/certbot
  4. Navigate to the storage location for your SSL certificates generated by Certbot:
    cd /data/certbot/conf/live/<CUSTOMERPORTAL HOST NAME>
  5. Replace the fullkey.pem and privkey.pem files with your certificates
  6. Restart the Nginx server within the Customer Portal:
    docker-compose exec app sv restart nginx

Your docker-compose.yml file should look something like this:

version: 'X.x'
services:
app:
build:
context: .
dockerfile: Dockerfile
image: sonarsoftware/customerportal:stable
container_name: sonar-customerportal
restart: always
tty: true
ports:
- "80:80"
- "443:443"
volumes:
- ./deploy/conf/nginx/sonar-customerportal.template:/etc/nginx/conf.d/sonar-customerportal.template
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
- ./public/assets/img/logo.png:/var/www/html/public/assets/img/logo.png
- ./public/assets/img/cover.png:/var/www/html/public/assets/img/cover.png
- storage:/var/www/html/storage
env_file:
- .env
environment:
REDIS_HOST: redis
depends_on:
- redis

redis:
image: redis:5.0.4-alpine
restart: always

# certbot:
# image: certbot/certbot
# restart: always
# entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
# volumes:
# - ./data/certbot/conf:/etc/letsencrypt
# - ./data/certbot/www:/var/www/certbot

watchtower:
image: v2tec/watchtower
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: sonar-customerportal

volumes:
storage:
driver: local

What about Portal Updates?

After you update your Sonar portal to the newest version, customizations will be cleared. While you could manually upload the custom files back into the upgraded portal, a more common method to reintroduce these customizations would be through synchronizing a fork. Below is the GitHub recommended approach to doing this:

The most up to date version of this information is available at https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/syncing-a-fork

Syncing a fork

Sync a fork of a repository to keep it up-to-date with the upstream repository.

Before you can sync your fork with an upstream repository, you must configure a remote that points to the upstream repository in Git.

  1. Open Terminal.
  2. Change the current working directory to your local project.
  3. Fetch the branches and their respective commits from the upstream repository. Commits to master will be stored in a local branch, upstream/master.
    $ git fetch upstream
    > remote: Counting objects: 75, done.
    > remote: Compressing objects: 100% (53/53), done.
    > remote: Total 62 (delta 27), reused 44 (delta 9)
    > Unpacking objects: 100% (62/62), done.
    > From https://github.com/ORIGINAL_OWNER/ORIGINAL_REPOSITORY
    > * [new branch] master -> upstream/master
  4. Check out your fork's local master branch.
    $ git checkout master
    > Switched to branch 'master'
  5. Merge the changes from upstream/master into your local master branch. This brings your fork's master branch into sync with the upstream repository, without losing your local changes.
    $ git merge upstream/master
    > Updating a422352..5fdff0f
    > Fast-forward
    > README | 9 -------
    > README.md | 7 ++++++
    > 2 files changed, 7 insertions(+), 9 deletions(-)
    > delete mode 100644 README
    > create mode 100644 README.md
    If your local branch didn't have any unique commits, Git will instead perform a "fast-forward":
    $ git merge upstream/master
    > Updating 34e91da..16c56ad
    > Fast-forward
    > README.md | 5 +++--
    > 1 file changed, 3 insertions(+), 2 deletions(-)

How did we do?

Troubleshooting the Customer Portal

Contact