Browse Source

Add param to disable SSL, sort errors first

Sacha Bron 2 months ago
parent
commit
9fca874eb6
8 changed files with 116 additions and 5 deletions
  1. 5 1
      components/ServiceCard.tsx
  2. 71 0
      config/services.ts
  3. 8 0
      package-lock.json
  4. 1 0
      package.json
  5. 13 3
      pages/api/status.ts
  6. 5 1
      pages/index.tsx
  7. 12 0
      static/style/global.css
  8. 1 0
      types/serviceChecks.ts

+ 5 - 1
components/ServiceCard.tsx

@@ -9,7 +9,11 @@ type ServiceCardProps = {
 
 const ServiceCard = ({ serviceStatus }: ServiceCardProps) => {
   return <div className={styles.line}>
-    <h3><StatusDot up={serviceStatus.online} />{serviceStatus.service.name}</h3>
+    <h3>
+      <StatusDot up={serviceStatus.online} />
+      { serviceStatus.service.name }
+      { serviceStatus.service.url && <a href={ serviceStatus.service.url }>&#x1F517;</a> }
+    </h3>
     {serviceStatus.message && <small><code>{serviceStatus.message}</code></small>}
   </div>
 };

+ 71 - 0
config/services.ts

@@ -14,6 +14,77 @@ const services: Array<Service> = [
     description: `Main website of FIXME.`,
     url: 'https://fixme.ch/',
   },
+  {
+    id: 'FIXME Wiki',
+    name: 'FIXME Wiki',
+    serviceCheck: {
+      type: 'URL',
+      params: {
+        url: 'https://fixme.ch/wiki'
+      }
+    },
+    public: true,
+    description: `FIXME wiki`,
+    url: 'https://fixme.ch/wiki',
+    wiki: 'https://fixme.ch/wiki/Main_Page',
+  },
+  {
+    id: 'FIXME Etherpad',
+    name: 'FIXME Etherpad',
+    serviceCheck: {
+      type: 'URL',
+      params: {
+        url: 'https://pad.fixme.ch'
+      }
+    },
+    public: true,
+    description: `Etherpad allows you to edit documents collaboratively in real-time, much like a live multi-player editor that runs in your browser.`,
+    url: 'https://pad.fixme.ch',
+    wiki: 'https://fixme.ch/wiki/Etherpad',
+  },
+  {
+    id: 'Home Assistant',
+    name: 'Home Assistant',
+    serviceCheck: {
+      type: 'URL',
+      params: {
+        url: 'https://ha.fixme.ch'
+      }
+    },
+    public: true,
+    description: `Open source home automation that puts local control and privacy first.`,
+    url: 'https://ha.fixme.ch',
+    wiki: 'https://fixme.ch/wiki/Home_Assistant',
+  },
+  {
+    id: 'Power Consumption Graph',
+    name: 'Power Consumption Graph',
+    serviceCheck: {
+      type: 'URL',
+      params: {
+        url: 'https://power.fixme.ch'
+      }
+    },
+    public: true,
+    description: `Real time hackerspace power consumption`,
+    url: 'https://power.fixme.ch',
+    wiki: 'https://fixme.ch/wiki/Power',
+  },
+  {
+    id: 'Network Router',
+    name: 'Network Router',
+    serviceCheck: {
+      type: 'URL',
+      params: {
+        url: 'https://router.fixme.ch',
+        disableSSLVerification: true,
+      }
+    },
+    public: true,
+    description: `Main router at FIXME`,
+    url: 'https://router.fixme.ch',
+    wiki: 'https://fixme.ch/wiki/Router',
+  },
   {
     id: 'orbital',
     name: 'Orbital',

+ 8 - 0
package-lock.json

@@ -651,6 +651,14 @@
       "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
       "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
     },
+    "axios": {
+      "version": "0.21.1",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
+      "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
+      "requires": {
+        "follow-redirects": "1.13.1"
+      }
+    },
     "babel-plugin-syntax-jsx": {
       "version": "6.18.0",
       "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",

+ 1 - 0
package.json

@@ -8,6 +8,7 @@
     "type-check": "tsc"
   },
   "dependencies": {
+    "axios": "^0.21.1",
     "next": "latest",
     "react": "^16.12.0",
     "react-dom": "^16.12.0"

+ 13 - 3
pages/api/status.ts

@@ -1,14 +1,24 @@
 import { NextApiRequest, NextApiResponse } from 'next';
-import {Service, ServiceStatus} from '../../types';
+import { Service, ServiceStatus } from '../../types';
 import services from '../../config/services';
+import axios from 'axios';
+import https from 'https';
 
 export const runCheckService: (service: Service) => Promise<ServiceStatus> = async (service: Service) => {
   switch (service.serviceCheck.type) {
     case "URL": {
       const { params } = service.serviceCheck;
 
-      try {const response = await fetch(params.url);
-        if (response.ok) {
+      try {
+        const agent = new https.Agent({
+          rejectUnauthorized: !params.disableSSLVerification ?? true
+        });
+
+        const response = await axios.get(params.url, {
+          httpsAgent: agent
+        });
+
+        if (response.status >= 200 && response.status < 300) {
           return { service, online: true };
         } else {
           return { service, online: false, message: `Error: ${response.statusText}` };

+ 5 - 1
pages/index.tsx

@@ -5,7 +5,11 @@ import {ServiceStatus} from "../types";
 
 const RenderServices = ({ status }: { status: ServiceStatus[] }) => {
   return <>
-    {status.map(serviceStatus => <ServiceCard serviceStatus={serviceStatus} key={serviceStatus.service.id} />)}
+    {
+      status
+        .sort((a: ServiceStatus, b: ServiceStatus) => (!b.online) ? 1 : -1)
+        .map(serviceStatus => <ServiceCard serviceStatus={serviceStatus} key={serviceStatus.service.id} />)
+    }
     </>;
 };
 

+ 12 - 0
static/style/global.css

@@ -114,3 +114,15 @@ h1 img {
     height: 2em;
     margin-right: 12px;
 }
+
+h3 {
+    margin-top: 0px;
+    margin-bottom: 15px;
+}
+
+h3 a {
+    text-decoration: none;
+    font-size: 0.5em;
+    font-size: 0.7em;
+    padding-left: 7px;
+}

+ 1 - 0
types/serviceChecks.ts

@@ -4,6 +4,7 @@ export interface ServiceCheckUrl extends ServiceCheck {
   type: 'URL',
   params: {
     url: string;
+    disableSSLVerification?: boolean; // default is false
   }
 }