OpenWISP WiFi Login Pages: Project Report

In the Google Summer of Code 2021, I have contributed to OpenWISP to bring professional efficiency to the OpenWISP WiFi Login Pages. This summer around 65 commits got merged into the master branch. The Project Kanban board consists of more than 70 cards (including issues and 35 plus PRs).

OpenWISP-WiFi-Login-Pages | GSoC Project Report Video

Aim of Project

The primary aim of this project was to bring professional efficiency by reducing boilerplate code, reducing the number of configuration lines with additions of some important features like multi-language translation support, reusable token validation, server-side logging, and faster response time by reducing build size. Increasing test coverage (greater than 95 percent) and adding headless browser tests for success and failure responses with interactions between different pages.

Other than the main features, I worked on some other features like loading configs of all organizations at runtime because earlier all configs were loaded in the main chunk, password-reveal feature, modal content fetching, reusable logout handler, UI & UX issues, and lots of optimization in solving other issues.

Project Details

OpenWISP WiFi Login Pages provides a unified and consistent user experience for public/private WiFi services by replacing the captive/login page of a WiFi service by integrating the OpenWISP Radius API to provide the features like Social Login, SAML, Mobile phone verification, multi-organization support with different themes, multi-language support and more.

During the coding period in GSoC, I worked on many major and minor pull requests. So instead of focussing on all the PRs and features, I will be highlighting the major features developed during the GSoC period.

Major Development Milestones

Multi-language translation (i18n) support

Previously, all the translations were defined in the configuration file of each organization, repeating the same text again and again, which made it difficult to update translations.

Demonstrating translation support in OpenWISP WiFi Login Pages

So after following the DRY principle and mentor suggestions, this feature of get text-like translation was implemented, and instead of loading all language translations at a time we thought to separate each language (including English) chunks and loading them dynamically when needed, which helped in reducing loading time. This feature includes customization features such as customizing the translation for a specific language ({language_code}.custom.po) as well as customizing translation for a specific organization and language ({orgSlug}_{language_code}.custom.po ). This feature also supports preferred language detection from the browser. Detailed info about this is present in docs.
Related work:

Reducing Configuration lines and support for the default configuration

The main motive of this feature was to reduce the size or number of lines of the configuration file (earlier, a lot of boilerplate was present) by adding support for default configuration ensuring that backward compatibility is maintained. After developing these features, configuration lines got reduced by 80 percent, and dynamic loading of each organization configuration is now possible.

Configuration creation and customization in OpenWISP WiFi Login Pages

Some key features are:

  • If the configuration file of a specific organization misses a piece of configuration, then the default configuration is used to generate a complete configuration such that the project keeps working.
  • Removing specific sections of the configuration by using the null keyword.
  • Earlier configuration of all organizations was present in the main chunk, so to resolve this dynamic loading of configuration at runtime was implemented. I also added the removal of the default organization configuration from the production build as the default organization is only used in the development version.
  • Support for the reverse mechanism of proxy URLs in the server.

More info about this is present in the docs.

Related work:

Optimizations to reduce the main chunk size

The main chunk size needs to be reduced to improve the website performance and load faster. There were various entry points already present to split the chunks, but to optimize and reduce the size of the main and other chunks it was required to optimize the code and implement dynamic loading of dependency. Features like translation support and reducing configuration lines also helped a lot with this optimization. Compressing assets, minifying code, caching, and support for gzipped as well as brotli plugin also helped in serving these contents faster. As a result, the main chunk size got reduced from 800 Kib to 250Kib with the DOM content load time of 250ms.

OpenWISP WiFi Login Pages build output

Related work:

Server-side logging

In real life, we all know that the server can crash or stop responding due to some randomly appearing bugs. Nothing is perfect, it gets better day by day. So to monitor such things, we need logging support in our application.

Demonstration of server-side logging in OpenWISP WiFi Login Pages

To monitor server crashes, errors, warnings, and HTTP requests, we were in need of implementing a feature like this. So I tried to make an error handler wrapper with advanced logging implementation using Winston and morgan. This server-side logging uses morgan middleware with Winston to create a logger which can log HTTP requests with other logs. It is very much configurable by using some environment variables like LOG_LEVELand more. Logging files can also be changed by using environment variables defined in the server-side logging configuration docs.

Related work:

Headless browser tests

These tests have more significance because these are the tests that test interfaces and interactions using headless browser automation. To implement these tests we used selenium and jest in OpenWISP WiFi Login Pages.

Browser tests (headless disabled) in OpenWISP WiFi Login Pages

These browser-based tests include various interactions between different components and flow such as login, register, change password, change phone number, verify phone number, password reset, password confirm and change the language flow. These tests also helped us to merge dependabot PRs for updating dependencies.

Related work:

Reusable token validation and User data

As OpenWISP WiFi Login Pages support features like auto-login, it was important to validate stored tokens for security purposes. Earlier, the validating token was repeated in many places. To remove this repetition the mentor, came up with an idea to make it reusable.

After implementation of reusable token validation, a single API request to validate the token is made which helps in improving the web performance. Implementation of things like user data and set user data is now centralized in the state management, which helps in changing state without repetition and boilerplate code.

Related work:

  • [feature] Reusable auth token validation logic #242 (This includes 5 commits reusable auth token with user data, fixed unnecessary calling of validating token API, removed trigger of phone number validation when loading status page, removed username error for inactive users and captive portal login on just authentication)

Reveal Password Feature

On mobile devices dealing with the password field was annoying. So we needed a lightweight implementation of this feature to toggle passwords. To increase the user experience, improvements like toggling all the password fields on the click of the eye icon and shifting focus to the clicked field were also implemented.

Password reveal feature demonstration

Related work:

Tests and Coverage

Coding Ain’t Done ’Til All the Tests Run

Tests and Coverage in OpenWISP WiFi Login Pages

I wrote many tests to increase the test coverage of each file. This thing of writing tests was new for me, and my mentor advised me to write the failing tests first and then solve the problem on the purpose, which helped me in writing many tests. Sometimes it is important to do the testing of the test, so I introduced bugs on purpose so that tests will catch them. As a result, we were able to accomplish the coverage to be more than 95 percent. This percentage will surely increase more in the future.

Related work:

Some other observable features

Deployment

Without deployment, the project has no significance. Below are some deployed versions of the organization that uses OpenWISP WiFi Login Pages.

Deployed versions of OpenWISP WiFi Login Pages

The Experience

The GSoC journey was full of excitement and learning for me. I am a sophomore and it was a very joyful moment for me to get selected in GSoC and do open source contributions in organizations like OpenWISP. The project maintainer and mentor Federico Capoano( @nemesisdesign ) guided me so well. The mentor was so helpful, whenever I got stuck on some issue he guided me to think in a different approach. I am very grateful to my mentor for helping me from the very first day of community bonding to the last day of project accomplishment.

The journey was full of experiences. The following are the important ones:

  1. Internationalization (i18n) support: This was the first time I was adding this support in React. We needed to add this support without breaking the current code and configuration of the organization. Mentor discussed this feature with me at a meeting and we decided to use translation placeholder tags and gettext because we need features like customizing language. This was the biggest change in this project with a lot of discussions.
  2. Code Quality and Documentation: I made a lot of major contributions to this open-source project so it was a need to maintain good code quality and documentation so that future contributors found it easy to contribute and it is up to the standard. The mentor helped me to attain this quality by providing regular reviews to my pull requests.
  3. Testing (TDD): It also plays an important role here because It is needed to increase the project coverage. Initially, it was not easy for me to write jest tests but over time I learned a lot of things related to test-driven development, which helped me in increasing coverage and writing headless browser tests.
  4. Research and Learn: To get something done we always have to discover and learn. In this project, there were a lot of things like merging and removing specific things from deeply nested objects, i18n support, redux, jest tests, selenium tests, and much more which need proper research. It was a fun experience for me to learn so many things to build each feature. Every feature was full of learning with great mentor advice.
  5. Open-source: Last but not least, I got this opportunity all due to open-source. I like the way a group of like-minded people contribute and collaborate for a good cause. With lots of contributions, I collaborated with the awesome and helpful community and mentors. We discussed many things related to project development on gitter which helps me to contribute in an effective and faster way.

What’s next?

The GSoC 2021 is going to end soon, but I will continue contributing to open-source and OpenWISP. I will continue solving bugs and adding more features to OpenWISP WiFi Login Pages. OpenWISP contains many core modules and supports modular development. I will continue contributing to those core modules to learn more about the networking stuff and development processes.

Thanks to Google Summer of Code and OpenWISP for providing me this opportunity full of learning and experiences.

Member @openwisp | GSoC’21 @openwisp | Season Of @KDE, OS-Leader @anitab-org | Contributing to Open-Source to learn from the community.