A web application to help check for domain or SSL/TLS certificate expirations.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Go to file
Jérémy Lecour 46141c7999
Merge pull request #147 from Evolix/dependabot/npm_and_yarn/url-parse-1.5.10
8 months ago
app Icann is the new Whois provider for .org domains 8 months ago
bin Upgrade to Rails 6.1 12 months ago
config Disable ecdsa-sha2 keys for SSH 12 months ago
db update schema.rb 8 months ago
lib Remove "require" deprecated by Zeitwerk 4 years ago
log Setup rails 5 years ago
public Setup rails 5 years ago
script Update production deployment script 12 months ago
test Icann is the new Whois provider for .org domains 8 months ago
tmp Setup rails 5 years ago
vendor Setup rails 5 years ago
.browserslistrc upgrade to webpacker 4 4 years ago
.gitignore Ignore local version of check_http 12 months ago
.rubocop.yml Increase max line length to 120 5 years ago
.travis.yml Travis : use Ubuntu 18 2 years ago
Capfile Fix deployement with webpacker 5 years ago
Gemfile Fix systemd unit for Puma 5 12 months ago
Gemfile.lock bundle update 8 months ago
Guardfile Adding ssl tests in Guardfile. 5 years ago
INSTALL.md Update NodeJS minimum version 2 years ago
LICENSE Add license 5 years ago
README.md Add license to README.md 5 years ago
Rakefile Basic rubocop configuration 5 years ago
babel.config.js Updates for Rails 6.0 4 years ago
config.ru Upgrade to Rails 6.1 12 months ago
package-lock.json npm update 8 months ago
package.json Migrate babel and postcss configs 4 years ago
postcss.config.js Migrate babel and postcss configs 4 years ago
yarn.lock Bump url-parse from 1.5.6 to 1.5.10 8 months ago


Chexpire Build Status

A web application to help check for domain or SSL/TLS certificate expirations.

Shakespeare quote: « An SSL error has occured and a secure connection to the server cannot be made. »

How-To Add a new check kind


  • write a job for executing and updating a check instance of your kind and use CheckLogger to log important event during a check execution.
  • Write a CheckProcessor class to perform theses jobs at regular interval.
  • For each notification channel, implement the code that notify the user when the date will expires soon or when there are recurrent failures.

Start by appending a new kind into the Check model at the enum :kind line.

Write a job and the check execution

The job takes a Check instance as an argument and is responsible for performing the check and updating the following dates fields for the check instance:

  • mandatory: last_run_at, immediately when the execution is starting
  • mandatory: domain_expires_at
  • mandatory: last_success_at, when no problems have occured during the verification and fields have been updated
  • optional: domain_created_at, domain_updated_at, when the kind of check allows them

The code architecture is up to you and can vary depending on the check, but most of time you should write a service which will execute something and parse the response. Then you'll return a simple response object which responds to methods used for updating check fields in the job.

Look at the SSL and Domain implementations for examples.


This is not currently required, but you should use the CheckLogger class to emit log events at important steps of a check execution (especially when error occurs): this can help in case of problems. A single CheckLogger instance is attached to a check execution and fill a CheckLog model instance with various contents. Looks into the code to see supported events.


A processor is responsible for executing checks at regular interval, selectively or not, depending of your needs. Basically, it performs your job for all relevant checks.

Create a processor dedicated for your check kind. The class should include the CheckProcessor module and respond to the following methods :

  • configuration_key: returns the key name of configuration in chexpire configuration file. For instance: checks_domain
  • scope: returns the checks scope used by each resolver. Generally, this should be the base scope defined into the CheckProcessor module, filtered by your check kind (ie: base_scope.your_kind)
  • resolvers: returns an array of methods which returns checks to execute. Allows conditional checks depending of various checks criterias such as far known expiry date, failing checks etc… Looks into the CheckProcessor for available resolvers methods or write your own. use resolve_all resolver if you want execute all of your check at each execution.
  • process: must execute or enqueue your job for a given check as argument. Note: because the processor is called into a task, and to take profit of a interval configuration parameter, it's better to execute the job synchronously in this method.


Each check kind can have configuration. Looks for other checks configuration for examples, such as checks_domain configuration in config/chexpire.defaults.yml file.

Schedule a task

Write a task in lib/tasks/checks.rake under the namespaces checks:sync_dates and invoke the sync_dates method of your processor. Schedule to run it periodically in config/schedule.rb, or list the task in the all alias which is the default processor scheduler.


Finally, you have to write the way the checks will be notified to theirs users. For each notifier channel (email, …) you need to write the way you'll notify the users when theirs check expiry dates matches their Notifications records.

First, add your checks kinds and these notifications definitions in the base class for notifier: app/services/notifier/channels/base.rb : in the notify method, for your new check kind, a specific method will be called in each notifier. For example, in the email channel, a specific mailer action is called for the check kind (domain, ssl…) Then, in each notifier class, implements the details of this method. If you want to ignore a notification for a given channel, simply write the method and do nothing, or use the supports? method and returns false.

For the email channel you'll have to write a new mailer action with these views. Take the SSL kind files as an example. Preview your mailer in a browser by editing test/mailers/previews/notifications_mailer_preview.rb file like other kinds and follow the comments in this file.

Handle recurrent failures

When our execution system fails a given number of consecutive times, the user will be notified. This is a different workflow from the expiration notifications :

  • this is independant from the notifications configured from the user
  • the user is notified to the owner of the check at the email address of the account (User#email)
  • all checks in error for a same user are sent in a single email

With a new check kind, you only need to tweek the mailer views to supports their new check kind. Follow app/views/recurrent_failures.{fr,en}.{text.html}.erb views and create similar partial of current kinds like _ssl_recurrent_failures.* for your new kind.

To preview the email, you have to enhance the seeds with a few checks of your new kind, and open http://localhost:3000/rails/mailers/notifications_mailer/recurrent_failures .


chexpire is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License along with this program. If not, see http://www.gnu.org/licenses/.