Skip to content
This repository was archived by the owner on Feb 18, 2025. It is now read-only.

RangeError: Invalid time value #24

Closed
Bortnyak opened this issue Oct 10, 2019 · 9 comments
Closed

RangeError: Invalid time value #24

Bortnyak opened this issue Oct 10, 2019 · 9 comments

Comments

@Bortnyak
Copy link

I found where is the problem.

There is a function:
issue2-1
I use this function like this:
issue2-2

If you don't set port 443 - everything is OK. Setting a port to 443 give us extended information about ssl errors (e.g. "Host: is not in the cert's altnames:") But if you set port 443 function works correctly only one time, next time when I call this function it leads to the crash.

issue2-3

@Bortnyak
Copy link
Author

Bortnyak commented Oct 10, 2019

const getSslDetails = async ({ url }) => {
  const domainParse = parseDomain(url);
  const result =  await sslChecker(${domainParse.subdomain ? domainParse.subdomain + "." : ""}${domainParse.domain}.${domainParse.tld}, { method: "GET", port: 443 });
  return result;
}

      let sslInfo1 = {};
      try {
        sslInfo1 = await getSslDetails({ url: monitor.url });
      } catch (e) {
        sslInfo1.e = e.reason;
        const error = "Certificate error";
        logger.error(error, e);
      }
      console.log("sslInfo1: ", sslInfo1);

      let sslInfo2 = {};
      try {
        sslInfo2 = await getSslDetails({ url: monitor.url });
      } catch (e) {
        sslInfo2.e = e.reason;
        const error = "Certificate error";
        logger.error(error, e);
      }
      console.log("sslInfo2: ", sslInfo2);

That code will crash.

@gabrieldissotti
Copy link

I'm receving a same error when I do the second request, but works normally at first request

@dyaa
Copy link
Owner

dyaa commented Dec 20, 2019

@gabrieldissotti Can you please provide a sample of your code?

@Bortnyak
Copy link
Author

@gabrieldissotti I solve this issue, just compile from ts to js.
Maybe you will find the problem.
This code works perfectly for me.
`

import * as https from "https";

const checkPort = port => !Number.isNaN(parseFloat(port)) && Math.sign(port) === 1;
const getDaysBetween = (validFrom, validTo) => Math.round(Math.abs(+validFrom - +validTo) / 8.64e7);
const getDaysRemaining = (validFrom, validTo) => {
  const daysRemaining = getDaysBetween(validFrom, validTo);
  if (new Date(validTo).getTime() < new Date().getTime()) {
    return -daysRemaining;
  }
  return daysRemaining;
};

const sslChecker = ({
  host, options = {
    agent: false,
    method: "HEAD",
    port: 443,
    rejectUnauthorized: true,
  },
}) => new Promise((resolve, reject) => {
  if (!checkPort(options.port)) {
    reject(Error("Invalid port"));
  }
  try {
    const req = https.request(Object.assign({ host }, options), (res) => {
      /* eslint-disable */
      const { valid_from, valid_to } = res.connection.getPeerCertificate();
      const validFrom = new Date(valid_from);
      const validTo = new Date(valid_to);
      /* eslint-enable */
      resolve({
        daysRemaining: getDaysRemaining(validFrom, validTo),
        valid: res.socket
          .authorized || false,
        validFrom: validFrom.toISOString(),
        validTo: validTo.toISOString(),
      });
    });
    req.on("error", reject);
    req.end();
  } catch (e) {
    reject(e);
  }
});

export default {
  sslChecker,
};

@rahuldeojoshi
Copy link

rahuldeojoshi commented Jan 15, 2020

@dyaa Same issue as @gabrieldissotti. Below is my code (Node.js)

const sslChecker = require('ssl-checker')

var urls = ['apple.com', 'google.com', 'microsoft.com', 'swift.org'];
var minutes = .01,
    interval = minutes * 60 * 1000;

setInterval(() => {
    // loop
    urls.forEach(element => {
        // Verify cert
        sslChecker(element, {
            method: "GET",
            port: 443
        }).then(
            console.info
        ).catch((err) => {
            // error
            console.log('It is an error (ssl-checker)...!!!' + ' Website: ' + element)
        });
    });
}, interval);

@gabrieldissotti
Copy link

gabrieldissotti commented Jan 15, 2020

Hi guys, I have solved.

First, if you want check ssl of many domains, you need use a NodeJs API, because clients can be blocked by CORS.

Use this code with Node v10.x

install axios with "npm i axios".

create this file test.js

const axios = require('axios');
const https = require('https');
const domains = [
  { dns: 'facebook.com' },
  { dns: 'iclouds.com.br' },
]


const getDaysBetween = (validFrom, validTo) => Math.round(Math.abs(+validFrom - +validTo) / 8.64e7);
const getDaysRemaining = (validTo) => {
  const daysRemaining = getDaysBetween(new Date(), validTo);
  if (new Date(validTo).getTime() < new Date().getTime()) {
    return -daysRemaining;
  }
  return daysRemaining;
};

function handleDomain ({ dns, path, port, method }) {

  const requestUrl = 
    'https://' 
    + dns 
    + (port ? ':' + port : '')
    + (path ? '/' + path : '') ;

  return new Promise((resolve, reject) => axios({
    url: requestUrl,
    method: method || 'GET',
    httpsAgent: new https.Agent({ rejectUnauthorized: false }),
    timeout: 80000,
  }).then(response => {
    const connection = response.request.res.client.ssl;

    const { valid_from, valid_to } = connection.getPeerCertificate();
    const validFrom = new Date(valid_from);
    const validTo = new Date(valid_to);

    resolve({
      domain: dns,
      daysRemaining: getDaysRemaining(validTo),
      valid: connection.authorized || false,
      validFrom: validFrom.toISOString(),
      validTo: validTo.toISOString(),
    });
  }).catch(err => {
    return resolve({ 
      domain: dns,
      error: err.message
    })
  })
)
}

function handleMultipleDomains(req, res) {
  try {
    const requests = domains.map(handleDomain)
  
    return Promise.all(requests).then((data) => console.log(data))
  } catch (error) {
    return res.json({ error: error.message})
  }
}

handleMultipleDomains()

run with node test.js

@rahuldeojoshi
Copy link

@gabrieldissotti This is great. Thanks.

@illusdolphin
Copy link

illusdolphin commented May 17, 2020

Issue itself is described in nodejs/node#3940, solution can be just adding an option agent with maxCachedSessions = 0:
const validationResult = await sslChecker(host, { agent: new https.Agent({ maxCachedSessions: 0 }) });

nikitaeverywhere added a commit to nikitaeverywhere/ssl-checker that referenced this issue Nov 3, 2020
nikitaeverywhere added a commit to nikitaeverywhere/ssl-checker that referenced this issue Nov 3, 2020
nikitaeverywhere added a commit to nikitaeverywhere/ssl-checker that referenced this issue Nov 3, 2020
nikitaeverywhere added a commit to nikitaeverywhere/ssl-checker that referenced this issue Nov 3, 2020
@dyaa dyaa closed this as completed in c730d7a Nov 4, 2020
@dyaa
Copy link
Owner

dyaa commented Nov 4, 2020

Big thanks to @ZitRos, This should be fixed now in version 2.0.7

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants