1
.env
@ -24,3 +24,4 @@ REACT_APP_WHO_API_KEY=''
|
||||
# API_CORS_ORIGIN='*' # Enable CORS, by setting your allowed hostname(s) here
|
||||
# API_ENABLE_RATE_LIMIT='true' # Enable rate limiting for the API
|
||||
# REACT_APP_API_ENDPOINT='/api' # The endpoint for the API (can be local or remote)
|
||||
# ENABLE_ANALYTICS='false' # Enable Plausible hit counter for the frontend
|
||||
|
4
.gitignore
vendored
@ -9,12 +9,14 @@
|
||||
/build/
|
||||
|
||||
# ------------------------
|
||||
# DEPLOYMENT
|
||||
# BUILT FILES
|
||||
# ------------------------
|
||||
dist/
|
||||
.vercel/
|
||||
.netlify/
|
||||
.webpack/
|
||||
.serverless/
|
||||
.astro/
|
||||
|
||||
# ------------------------
|
||||
# DEPENDENCIES
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Specify the Node.js version to use
|
||||
ARG NODE_VERSION=16
|
||||
ARG NODE_VERSION=21
|
||||
|
||||
# Specify the Debian version to use, the default is "bullseye"
|
||||
ARG DEBIAN_VERSION=bullseye
|
||||
@ -30,7 +30,7 @@ COPY package.json yarn.lock ./
|
||||
|
||||
# Run yarn install to install dependencies and clear yarn cache
|
||||
RUN apt-get update && \
|
||||
yarn install --production --frozen-lockfile --network-timeout 100000 && \
|
||||
yarn install --frozen-lockfile --network-timeout 100000 && \
|
||||
rm -rf /app/node_modules/.cache
|
||||
|
||||
# Copy all files to working directory
|
||||
@ -59,4 +59,4 @@ EXPOSE ${PORT:-3000}
|
||||
ENV CHROME_PATH='/usr/bin/chromium'
|
||||
|
||||
# Define the command executed when the container starts and start the server.js of the Node.js application
|
||||
CMD ["yarn", "serve"]
|
||||
CMD ["yarn", "start"]
|
||||
|
@ -124,4 +124,8 @@ const commonMiddleware = (handler) => {
|
||||
return nativeMode ? vercelHandler : netlifyHandler;
|
||||
};
|
||||
|
||||
module.exports = commonMiddleware;
|
||||
if (PLATFORM === 'NETLIFY') {
|
||||
module.exports = commonMiddleware;
|
||||
}
|
||||
|
||||
export default commonMiddleware;
|
||||
|
@ -1,5 +1,5 @@
|
||||
const axios = require('axios');
|
||||
const middleware = require('./_common/middleware');
|
||||
import axios from 'axios';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const convertTimestampToDate = (timestamp) => {
|
||||
const [year, month, day, hour, minute, second] = [
|
||||
@ -46,7 +46,7 @@ const getScanFrequency = (firstScan, lastScan, totalScans, changeCount) => {
|
||||
};
|
||||
};
|
||||
|
||||
const getWaybackData = async (url) => {
|
||||
const wayBackHandler = async (url) => {
|
||||
const cdxUrl = `https://web.archive.org/cdx/search/cdx?url=${url}&output=json&fl=timestamp,statuscode,digest,length,offset`;
|
||||
|
||||
try {
|
||||
@ -80,5 +80,5 @@ const getWaybackData = async (url) => {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = middleware(getWaybackData);
|
||||
module.exports.handler = middleware(getWaybackData);
|
||||
export const handler = middleware(wayBackHandler);
|
||||
export default handler;
|
||||
|
@ -1,6 +1,6 @@
|
||||
const dns = require('dns');
|
||||
const { URL } = require('url');
|
||||
const middleware = require('./_common/middleware');
|
||||
import dns from 'dns';
|
||||
import { URL } from 'url';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const DNS_SERVERS = [
|
||||
{ name: 'AdGuard', ip: '176.103.130.130' },
|
||||
@ -94,12 +94,12 @@ const checkDomainAgainstDnsServers = async (domain) => {
|
||||
return results;
|
||||
};
|
||||
|
||||
const handler = async (url) => {
|
||||
export const blockListHandler = async (url) => {
|
||||
const domain = new URL(url).hostname;
|
||||
const results = await checkDomainAgainstDnsServers(domain);
|
||||
return { blocklists: results };
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(blockListHandler);
|
||||
export default handler;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
const https = require('https');
|
||||
const middleware = require('./_common/middleware');
|
||||
import https from 'https';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const handler = async (url) => {
|
||||
const carbonHandler = async (url) => {
|
||||
|
||||
// First, get the size of the website's HTML
|
||||
const getHtmlSize = (url) => new Promise((resolve, reject) => {
|
||||
@ -48,5 +48,5 @@ const handler = async (url) => {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(carbonHandler);
|
||||
export default handler;
|
||||
|
@ -1,6 +1,6 @@
|
||||
const axios = require('axios');
|
||||
const puppeteer = require('puppeteer');
|
||||
const middleware = require('./_common/middleware');
|
||||
import axios from 'axios';
|
||||
import puppeteer from 'puppeteer';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const getPuppeteerCookies = async (url) => {
|
||||
const browser = await puppeteer.launch({
|
||||
@ -21,7 +21,7 @@ const getPuppeteerCookies = async (url) => {
|
||||
}
|
||||
};
|
||||
|
||||
const handler = async (url) => {
|
||||
const cookieHandler = async (url) => {
|
||||
let headerCookies = null;
|
||||
let clientCookies = null;
|
||||
|
||||
@ -54,5 +54,5 @@ const handler = async (url) => {
|
||||
return { headerCookies, clientCookies };
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(cookieHandler);
|
||||
export default handler;
|
||||
|
@ -1,9 +1,8 @@
|
||||
const dns = require('dns');
|
||||
const dnsPromises = dns.promises;
|
||||
const axios = require('axios');
|
||||
const middleware = require('./_common/middleware');
|
||||
import { promises as dnsPromises, lookup } from 'dns';
|
||||
import axios from 'axios';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const handler = async (url) => {
|
||||
const dnsHandler = async (url) => {
|
||||
try {
|
||||
const domain = url.replace(/^(?:https?:\/\/)?/i, "");
|
||||
const addresses = await dnsPromises.resolve4(domain);
|
||||
@ -41,5 +40,7 @@ const handler = async (url) => {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
|
||||
export const handler = middleware(dnsHandler);
|
||||
export default handler;
|
||||
|
||||
|
12
api/dns.js
@ -1,8 +1,8 @@
|
||||
const dns = require('dns');
|
||||
const util = require('util');
|
||||
const middleware = require('./_common/middleware');
|
||||
import dns from 'dns';
|
||||
import util from 'util';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const handler = async (url) => {
|
||||
const dnsHandler = async (url) => {
|
||||
let hostname = url;
|
||||
|
||||
// Handle URLs by extracting hostname
|
||||
@ -51,5 +51,5 @@ const handler = async (url) => {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(dnsHandler);
|
||||
export default handler;
|
||||
|
@ -1,7 +1,7 @@
|
||||
const https = require('https');
|
||||
const middleware = require('./_common/middleware'); // Make sure this path is correct
|
||||
import https from 'https';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const handler = async (domain) => {
|
||||
const dnsSecHandler = async (domain) => {
|
||||
const dnsTypes = ['DNSKEY', 'DS', 'RRSIG'];
|
||||
const records = {};
|
||||
|
||||
@ -53,5 +53,5 @@ const handler = async (domain) => {
|
||||
return records;
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(dnsSecHandler);
|
||||
export default handler;
|
||||
|
@ -1,7 +1,7 @@
|
||||
const https = require('https');
|
||||
const middleware = require('./_common/middleware');
|
||||
import https from 'https';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const handler = async (url) => {
|
||||
const featuresHandler = async (url) => {
|
||||
const apiKey = process.env.BUILT_WITH_API_KEY;
|
||||
|
||||
if (!url) {
|
||||
@ -45,5 +45,5 @@ const handler = async (url) => {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(featuresHandler);
|
||||
export default handler;
|
||||
|
@ -1,5 +1,5 @@
|
||||
const axios = require('axios');
|
||||
const middleware = require('./_common/middleware');
|
||||
import axios from 'axios';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const hasWaf = (waf) => {
|
||||
return {
|
||||
@ -7,7 +7,7 @@ const hasWaf = (waf) => {
|
||||
}
|
||||
};
|
||||
|
||||
const handler = async (url) => {
|
||||
const firewallHandler = async (url) => {
|
||||
const fullUrl = url.startsWith('http') ? url : `http://${url}`;
|
||||
|
||||
try {
|
||||
@ -110,5 +110,5 @@ const handler = async (url) => {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(firewallHandler);
|
||||
export default handler;
|
||||
|
@ -1,5 +1,5 @@
|
||||
const dns = require('dns');
|
||||
const middleware = require('./_common/middleware');
|
||||
import dns from 'dns';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const lookupAsync = (address) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
@ -13,11 +13,11 @@ const lookupAsync = (address) => {
|
||||
});
|
||||
};
|
||||
|
||||
const handler = async (url) => {
|
||||
const ipHandler = async (url) => {
|
||||
const address = url.replaceAll('https://', '').replaceAll('http://', '');
|
||||
return await lookupAsync(address);
|
||||
};
|
||||
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(ipHandler);
|
||||
export default handler;
|
||||
|
@ -1,7 +1,7 @@
|
||||
const axios = require('axios');
|
||||
const middleware = require('./_common/middleware');
|
||||
import axios from 'axios';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const handler = async (url, event, context) => {
|
||||
const headersHandler = async (url, event, context) => {
|
||||
try {
|
||||
const response = await axios.get(url, {
|
||||
validateStatus: function (status) {
|
||||
@ -15,5 +15,5 @@ const handler = async (url, event, context) => {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(headersHandler);
|
||||
export default handler;
|
||||
|
11
api/hsts.js
@ -1,7 +1,7 @@
|
||||
const https = require('https');
|
||||
const middleware = require('./_common/middleware');
|
||||
import https from 'https';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const handler = async (url, event, context) => {
|
||||
const hstsHandler = async (url, event, context) => {
|
||||
const errorResponse = (message, statusCode = 500) => {
|
||||
return {
|
||||
statusCode: statusCode,
|
||||
@ -45,6 +45,5 @@ const handler = async (url, event, context) => {
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
|
||||
export const handler = middleware(hstsHandler);
|
||||
export default handler;
|
||||
|
@ -1,7 +1,7 @@
|
||||
const axios = require('axios');
|
||||
const middleware = require('./_common/middleware');
|
||||
import axios from 'axios';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const handler = async (url) => {
|
||||
const httpsSecHandler = async (url) => {
|
||||
const fullUrl = url.startsWith('http') ? url : `http://${url}`;
|
||||
|
||||
try {
|
||||
@ -22,5 +22,5 @@ const handler = async (url) => {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(httpsSecHandler);
|
||||
export default handler;
|
||||
|
@ -1,8 +1,8 @@
|
||||
const axios = require('axios');
|
||||
const unzipper = require('unzipper');
|
||||
const csv = require('csv-parser');
|
||||
const fs = require('fs');
|
||||
const middleware = require('./_common/middleware');
|
||||
import axios from 'axios';
|
||||
import unzipper from 'unzipper';
|
||||
import csv from 'csv-parser';
|
||||
import fs from 'fs';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
// Should also work with the following sources:
|
||||
// https://www.domcop.com/files/top/top10milliondomains.csv.zip
|
||||
@ -14,7 +14,7 @@ const middleware = require('./_common/middleware');
|
||||
const FILE_URL = 'https://s3-us-west-1.amazonaws.com/umbrella-static/top-1m.csv.zip';
|
||||
const TEMP_FILE_PATH = '/tmp/top-1m.csv';
|
||||
|
||||
const handler = async (url) => {
|
||||
const rankHandler = async (url) => {
|
||||
let domain = null;
|
||||
|
||||
try {
|
||||
@ -66,6 +66,5 @@ return new Promise((resolve, reject) => {
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
|
||||
export const handler = middleware(rankHandler);
|
||||
export default handler;
|
||||
|
@ -1,9 +1,9 @@
|
||||
const axios = require('axios');
|
||||
const cheerio = require('cheerio');
|
||||
const urlLib = require('url');
|
||||
const middleware = require('./_common/middleware');
|
||||
import axios from 'axios';
|
||||
import cheerio from 'cheerio';
|
||||
import urlLib from 'url';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const handler = async (url) => {
|
||||
const linkedPagesHandler = async (url) => {
|
||||
const response = await axios.get(url);
|
||||
const html = response.data;
|
||||
const $ = cheerio.load(html);
|
||||
@ -33,17 +33,17 @@ const handler = async (url) => {
|
||||
if (internalLinks.length === 0 && externalLinks.length === 0) {
|
||||
return {
|
||||
statusCode: 400,
|
||||
body: JSON.stringify({
|
||||
body: {
|
||||
skipped: 'No internal or external links found. '
|
||||
+ 'This may be due to the website being dynamically rendered, using a client-side framework (like React), and without SSR enabled. '
|
||||
+ 'That would mean that the static HTML returned from the HTTP request doesn\'t contain any meaningful content for Web-Check to analyze. '
|
||||
+ 'You can rectify this by using a headless browser to render the page instead.',
|
||||
}),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return { internal: internalLinks, external: externalLinks };
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(linkedPagesHandler);
|
||||
export default handler;
|
||||
|
@ -1,9 +1,10 @@
|
||||
const middleware = require('./_common/middleware');
|
||||
import dns from 'dns';
|
||||
import URL from 'url-parse';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const dns = require('dns').promises;
|
||||
const URL = require('url-parse');
|
||||
// TODO: Fix.
|
||||
|
||||
const handler = async (url, event, context) => {
|
||||
const mailConfigHandler = async (url, event, context) => {
|
||||
try {
|
||||
const domain = new URL(url).hostname || new URL(url).pathname;
|
||||
|
||||
@ -71,11 +72,11 @@ const handler = async (url, event, context) => {
|
||||
} else {
|
||||
return {
|
||||
statusCode: 500,
|
||||
body: JSON.stringify({ error: error.message }),
|
||||
body: { error: error.message },
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(mailConfigHandler);
|
||||
export default handler;
|
||||
|
10
api/ports.js
@ -1,5 +1,5 @@
|
||||
const net = require('net');
|
||||
const middleware = require('./_common/middleware');
|
||||
import net from 'net';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
// A list of commonly used ports.
|
||||
const PORTS = [
|
||||
@ -34,7 +34,7 @@ async function checkPort(port, domain) {
|
||||
});
|
||||
}
|
||||
|
||||
const handler = async (url, event, context) => {
|
||||
const portsHandler = async (url, event, context) => {
|
||||
const domain = url.replace(/(^\w+:|^)\/\//, '');
|
||||
|
||||
const delay = ms => new Promise(res => setTimeout(res, ms));
|
||||
@ -84,5 +84,5 @@ const errorResponse = (message, statusCode = 444) => {
|
||||
return { error: message };
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(portsHandler);
|
||||
export default handler;
|
||||
|
@ -1,7 +1,7 @@
|
||||
const axios = require('axios');
|
||||
const middleware = require('./_common/middleware');
|
||||
import axios from 'axios';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const handler = async (url, event, context) => {
|
||||
const qualityHandler = async (url, event, context) => {
|
||||
const apiKey = process.env.GOOGLE_CLOUD_API_KEY;
|
||||
|
||||
if (!apiKey) {
|
||||
@ -18,5 +18,5 @@ const handler = async (url, event, context) => {
|
||||
return (await axios.get(endpoint)).data;
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(qualityHandler);
|
||||
export default handler;
|
||||
|
10
api/rank.js
@ -1,7 +1,7 @@
|
||||
const axios = require('axios');
|
||||
const middleware = require('./_common/middleware');
|
||||
import axios from 'axios';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const handler = async (url) => {
|
||||
const rankHandler = async (url) => {
|
||||
const domain = url ? new URL(url).hostname : null;
|
||||
if (!domain) throw new Error('Invalid URL');
|
||||
|
||||
@ -21,6 +21,6 @@ const handler = async (url) => {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(rankHandler);
|
||||
export default handler;
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
const handler = async (url) => {
|
||||
const redirects = [url];
|
||||
const got = await import('got');
|
||||
import got from 'got';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const redirectsHandler = async (url) => {
|
||||
const redirects = [url];
|
||||
try {
|
||||
await got.default(url, {
|
||||
await got(url, {
|
||||
followRedirect: true,
|
||||
maxRedirects: 12,
|
||||
hooks: {
|
||||
@ -23,7 +24,5 @@ const handler = async (url) => {
|
||||
}
|
||||
};
|
||||
|
||||
const middleware = require('./_common/middleware');
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(redirectsHandler);
|
||||
export default handler;
|
||||
|
@ -1,5 +1,5 @@
|
||||
const axios = require('axios');
|
||||
const middleware = require('./_common/middleware');
|
||||
import axios from 'axios';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const parseRobotsTxt = (content) => {
|
||||
const lines = content.split('\n');
|
||||
@ -31,7 +31,7 @@ const parseRobotsTxt = (content) => {
|
||||
return { robots: rules };
|
||||
}
|
||||
|
||||
const handler = async function(url) {
|
||||
const robotsHandler = async function(url) {
|
||||
let parsedURL;
|
||||
try {
|
||||
parsedURL = new URL(url);
|
||||
@ -67,5 +67,5 @@ const handler = async function(url) {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(robotsHandler);
|
||||
export default handler;
|
||||
|
@ -1,8 +1,8 @@
|
||||
const puppeteer = require('puppeteer-core');
|
||||
const chromium = require('chrome-aws-lambda');
|
||||
const middleware = require('./_common/middleware');
|
||||
import puppeteer from 'puppeteer-core';
|
||||
import chromium from 'chrome-aws-lambda';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const handler = async (targetUrl) => {
|
||||
const screenshotHandler = async (targetUrl) => {
|
||||
|
||||
if (!targetUrl) {
|
||||
throw new Error('URL is missing from queryStringParameters');
|
||||
@ -58,5 +58,5 @@ const handler = async (targetUrl) => {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(screenshotHandler);
|
||||
export default handler;
|
||||
|
@ -1,6 +1,8 @@
|
||||
const { https } = require('follow-redirects');
|
||||
const { URL } = require('url');
|
||||
const middleware = require('./_common/middleware');
|
||||
import { URL } from 'url';
|
||||
import followRedirects from 'follow-redirects';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const { https } = followRedirects;
|
||||
|
||||
const SECURITY_TXT_PATHS = [
|
||||
'/security.txt',
|
||||
@ -38,7 +40,7 @@ const isPgpSigned = (result) => {
|
||||
return false;
|
||||
};
|
||||
|
||||
const handler = async (urlParam) => {
|
||||
const securityTxtHandler = async (urlParam) => {
|
||||
|
||||
let url;
|
||||
try {
|
||||
@ -90,5 +92,5 @@ async function fetchSecurityTxt(baseURL, path) {
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(securityTxtHandler);
|
||||
export default handler;
|
||||
|
@ -1,9 +1,8 @@
|
||||
const middleware = require('./_common/middleware');
|
||||
import axios from 'axios';
|
||||
import xml2js from 'xml2js';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const axios = require('axios');
|
||||
const xml2js = require('xml2js');
|
||||
|
||||
const handler = async (url) => {
|
||||
const sitemapHandler = async (url) => {
|
||||
let sitemapUrl = `${url}/sitemap.xml`;
|
||||
|
||||
const hardTimeOut = 5000;
|
||||
@ -49,6 +48,6 @@ const handler = async (url) => {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(sitemapHandler);
|
||||
export default handler;
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
const middleware = require('./_common/middleware');
|
||||
import axios from 'axios';
|
||||
import cheerio from 'cheerio';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const axios = require('axios');
|
||||
const cheerio = require('cheerio');
|
||||
|
||||
const handler = async (url) => {
|
||||
const socialTagsHandler = async (url) => {
|
||||
|
||||
// Check if url includes protocol
|
||||
if (!url.startsWith('http://') && !url.startsWith('https://')) {
|
||||
@ -61,5 +60,5 @@ const handler = async (url) => {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(socialTagsHandler);
|
||||
export default handler;
|
||||
|
10
api/ssl.js
@ -1,7 +1,7 @@
|
||||
const tls = require('tls');
|
||||
const middleware = require('./_common/middleware');
|
||||
import tls from 'tls';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const handler = async (urlString) => {
|
||||
const sslHandler = async (urlString) => {
|
||||
try {
|
||||
const parsedUrl = new URL(urlString);
|
||||
const options = {
|
||||
@ -40,5 +40,5 @@ const handler = async (urlString) => {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(sslHandler);
|
||||
export default handler;
|
||||
|
@ -1,8 +1,8 @@
|
||||
const https = require('https');
|
||||
const { performance, PerformanceObserver } = require('perf_hooks');
|
||||
const middleware = require('./_common/middleware');
|
||||
import https from 'https';
|
||||
import { performance, PerformanceObserver } from 'perf_hooks';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const handler = async (url) => {
|
||||
const statusHandler = async (url) => {
|
||||
if (!url) {
|
||||
throw new Error('You must provide a URL query parameter!');
|
||||
}
|
||||
@ -55,5 +55,5 @@ const handler = async (url) => {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(statusHandler);
|
||||
export default handler;
|
||||
|
@ -1,7 +1,7 @@
|
||||
const Wappalyzer = require('wappalyzer');
|
||||
const middleware = require('./_common/middleware');
|
||||
import Wappalyzer from 'wappalyzer';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const handler = async (url) => {
|
||||
const techStackHandler = async (url) => {
|
||||
const options = {};
|
||||
|
||||
const wappalyzer = new Wappalyzer(options);
|
||||
@ -27,5 +27,5 @@ const handler = async (url) => {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(techStackHandler);
|
||||
export default handler;
|
||||
|
@ -1,6 +1,6 @@
|
||||
const axios = require('axios');
|
||||
const xml2js = require('xml2js');
|
||||
const middleware = require('./_common/middleware');
|
||||
import axios from 'axios';
|
||||
import xml2js from 'xml2js';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const getGoogleSafeBrowsingResult = async (url) => {
|
||||
try {
|
||||
@ -84,7 +84,7 @@ const getCloudmersiveResult = async (url) => {
|
||||
}
|
||||
};
|
||||
|
||||
const handler = async (url) => {
|
||||
const threatsHandler = async (url) => {
|
||||
try {
|
||||
const urlHaus = await getUrlHausResult(url);
|
||||
const phishTank = await getPhishTankResult(url);
|
||||
@ -99,5 +99,5 @@ const handler = async (url) => {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(threatsHandler);
|
||||
export default handler;
|
||||
|
14
api/tls.js
@ -1,9 +1,9 @@
|
||||
const axios = require('axios');
|
||||
const middleware = require('./_common/middleware');
|
||||
import axios from 'axios';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const MOZILLA_TLS_OBSERVATORY_API = 'https://tls-observatory.services.mozilla.com/api/v1';
|
||||
|
||||
const handler = async (url) => {
|
||||
const tlsHandler = async (url) => {
|
||||
try {
|
||||
const domain = new URL(url).hostname;
|
||||
const scanResponse = await axios.post(`${MOZILLA_TLS_OBSERVATORY_API}/scan?target=${domain}`);
|
||||
@ -12,18 +12,18 @@ const handler = async (url) => {
|
||||
if (typeof scanId !== 'number') {
|
||||
return {
|
||||
statusCode: 500,
|
||||
body: JSON.stringify({ error: 'Failed to get scan_id from TLS Observatory' }),
|
||||
body: { error: 'Failed to get scan_id from TLS Observatory' },
|
||||
};
|
||||
}
|
||||
const resultResponse = await axios.get(`${MOZILLA_TLS_OBSERVATORY_API}/results?id=${scanId}`);
|
||||
return {
|
||||
statusCode: 200,
|
||||
body: JSON.stringify(resultResponse.data),
|
||||
body: resultResponse.data,
|
||||
};
|
||||
} catch (error) {
|
||||
return { error: error.message };
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(tlsHandler);
|
||||
export default handler;
|
||||
|
@ -1,8 +1,8 @@
|
||||
const traceroute = require('traceroute');
|
||||
const url = require('url');
|
||||
const middleware = require('./_common/middleware');
|
||||
import url from 'url';
|
||||
import traceroute from 'traceroute';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const handler = async (urlString, context) => {
|
||||
const traceRouteHandler = async (urlString, context) => {
|
||||
// Parse the URL and get the hostname
|
||||
const urlObject = url.parse(urlString);
|
||||
const host = urlObject.hostname;
|
||||
@ -28,5 +28,5 @@ const handler = async (urlString, context) => {
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(traceRouteHandler);
|
||||
export default handler;
|
||||
|
@ -1,7 +1,7 @@
|
||||
const dns = require('dns').promises;
|
||||
const middleware = require('./_common/middleware');
|
||||
import dns from 'dns/promises';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const handler = async (url, event, context) => {
|
||||
const txtRecordHandler = async (url, event, context) => {
|
||||
try {
|
||||
const parsedUrl = new URL(url);
|
||||
|
||||
@ -29,5 +29,5 @@ const handler = async (url, event, context) => {
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(txtRecordHandler);
|
||||
export default handler;
|
||||
|
14
api/whois.js
@ -1,7 +1,7 @@
|
||||
const net = require('net');
|
||||
const psl = require('psl');
|
||||
const axios = require('axios');
|
||||
const middleware = require('./_common/middleware');
|
||||
import net from 'net';
|
||||
import psl from 'psl';
|
||||
import axios from 'axios';
|
||||
import middleware from './_common/middleware.js';
|
||||
|
||||
const getBaseDomain = (url) => {
|
||||
let protocol = '';
|
||||
@ -83,7 +83,7 @@ const fetchFromMyAPI = async (hostname) => {
|
||||
}
|
||||
};
|
||||
|
||||
const handler = async (url) => {
|
||||
const whoisHandler = async (url) => {
|
||||
if (!url.startsWith('http://') && !url.startsWith('https://')) {
|
||||
url = 'http://' + url;
|
||||
}
|
||||
@ -106,6 +106,6 @@ const handler = async (url) => {
|
||||
};
|
||||
};
|
||||
|
||||
module.exports = middleware(handler);
|
||||
module.exports.handler = middleware(handler);
|
||||
export const handler = middleware(whoisHandler);
|
||||
export default handler;
|
||||
|
||||
|
79
astro.config.mjs
Normal file
@ -0,0 +1,79 @@
|
||||
import { defineConfig } from 'astro/config';
|
||||
|
||||
// Integrations
|
||||
import svelte from '@astrojs/svelte';
|
||||
import react from "@astrojs/react";
|
||||
import partytown from '@astrojs/partytown';
|
||||
import sitemap from '@astrojs/sitemap';
|
||||
|
||||
// Adapters
|
||||
import vercelAdapter from '@astrojs/vercel/serverless';
|
||||
import netlifyAdapter from '@astrojs/netlify';
|
||||
import nodeAdapter from '@astrojs/node';
|
||||
import cloudflareAdapter from '@astrojs/cloudflare';
|
||||
|
||||
// Helper function to unwrap both Vite and Node environment variables
|
||||
const unwrapEnvVar = (varName, fallbackValue) => {
|
||||
const classicEnvVar = process?.env && process.env[varName];
|
||||
const viteEnvVar = import.meta.env[varName];
|
||||
return classicEnvVar || viteEnvVar || fallbackValue;
|
||||
}
|
||||
|
||||
// Determine the deploy target (vercel, netlify, cloudflare, node)
|
||||
const deployTarget = unwrapEnvVar('PLATFORM', 'node').toLowerCase();
|
||||
|
||||
// Determine the output mode (server, hybrid or static)
|
||||
const output = unwrapEnvVar('OUTPUT', 'hybrid');
|
||||
|
||||
// The FQDN of where the site is hosted (used for sitemaps & canonical URLs)
|
||||
const site = unwrapEnvVar('SITE_URL', 'https://web-check.xyz');
|
||||
|
||||
// The base URL of the site (if serving from a subdirectory)
|
||||
const base = unwrapEnvVar('BASE_URL', '/');
|
||||
|
||||
// Should run the app in boss-mode (requires extra configuration)
|
||||
const isBossServer = unwrapEnvVar('BOSS_SERVER', false);
|
||||
|
||||
// Initialize Astro integrations
|
||||
const integrations = [svelte(), react(), partytown(), sitemap()];
|
||||
|
||||
// Set the appropriate adapter, based on the deploy target
|
||||
function getAdapter(target) {
|
||||
switch(target) {
|
||||
case 'vercel':
|
||||
return vercelAdapter();
|
||||
case 'netlify':
|
||||
return netlifyAdapter();
|
||||
case 'cloudflare':
|
||||
return cloudflareAdapter();
|
||||
case 'node':
|
||||
return nodeAdapter({ mode: 'middleware' });
|
||||
default:
|
||||
throw new Error(`Unsupported deploy target: ${target}`);
|
||||
}
|
||||
}
|
||||
const adapter = getAdapter(deployTarget);
|
||||
|
||||
// Print build information to console
|
||||
console.log(
|
||||
`\n\x1b[1m\x1b[35m Preparing to start build of Web Check.... \x1b[0m\n`,
|
||||
`\x1b[35m\x1b[2mCompiling for "${deployTarget}" using "${output}" mode, `
|
||||
+ `to deploy to "${site}" at "${base}"\x1b[0m\n`,
|
||||
`\x1b[2m\x1b[36m🛟 For documentation and support, visit the GitHub repo: ` +
|
||||
`https://github.com/lissy93/web-check \n`,
|
||||
`💖 Found Web-Check useful? Consider sponsoring us on GitHub ` +
|
||||
`to help fund maintenance & development.\x1b[0m\n`,
|
||||
);
|
||||
|
||||
const redirects = {
|
||||
'/about': '/check/about',
|
||||
};
|
||||
|
||||
// Skip the marketing homepage for self-hosted users
|
||||
if (!isBossServer && isBossServer !== true) {
|
||||
redirects['/'] = '/check';
|
||||
}
|
||||
|
||||
// Export Astro configuration
|
||||
export default defineConfig({ output, base, integrations, site, adapter, redirects });
|
||||
|
17
fly.toml
Normal file
@ -0,0 +1,17 @@
|
||||
app = 'web-check'
|
||||
primary_region = 'lhr'
|
||||
|
||||
[build]
|
||||
|
||||
[http_service]
|
||||
internal_port = 3000
|
||||
force_https = true
|
||||
auto_stop_machines = true
|
||||
auto_start_machines = true
|
||||
min_machines_running = 0
|
||||
processes = ['app']
|
||||
|
||||
[[vm]]
|
||||
memory = '1gb'
|
||||
cpu_kind = 'shared'
|
||||
cpus = 1
|
10
netlify.toml
@ -2,11 +2,13 @@
|
||||
[build]
|
||||
base = "/"
|
||||
command = "yarn build"
|
||||
publish = "build"
|
||||
publish = "dist"
|
||||
functions = "api"
|
||||
|
||||
# Environmental variables and optional secrets
|
||||
[build.environment]
|
||||
PLATFORM = "netlify"
|
||||
PUBLIC_API_ENDPOINT = "/.netlify/functions"
|
||||
# Build configuration env vars (uncomment if you want to conigure these)
|
||||
# CI="false" # Set CI to false, to prevent warnings from exiting the build
|
||||
# CHROME_PATH='/usr/bin/chromium' # Path to Chromium binary
|
||||
@ -25,12 +27,6 @@
|
||||
status = 301
|
||||
force = true
|
||||
|
||||
# For router history mode, ensure pages land on index
|
||||
[[redirects]]
|
||||
from = "/*"
|
||||
to = "/index.html"
|
||||
status = 200
|
||||
|
||||
# Plugins
|
||||
[[plugins]]
|
||||
package = "netlify-plugin-chromium"
|
||||
|
126
package.json
@ -1,103 +1,73 @@
|
||||
{
|
||||
"name": "web-check",
|
||||
"version": "1.1.2",
|
||||
"private": false,
|
||||
"description": "All-in-one OSINT tool for analyzing any website",
|
||||
"repository": "github:lissy93/web-check",
|
||||
"type": "module",
|
||||
"version": "0.0.1",
|
||||
"homepage": "https://web-check.xyz",
|
||||
"license": "MIT",
|
||||
"author": {
|
||||
"name": "Alicia Sykes",
|
||||
"email": "alicia@omg.lol"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/Lissy93"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "netlify dev",
|
||||
"serve": "node server",
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"start": "node server",
|
||||
"start-pm": "pm2 start server.js -i max",
|
||||
"build": "astro check && astro build",
|
||||
"dev:vercel": "PLATFORM='vercel' npx vercel dev",
|
||||
"dev:netlify": "PLATFORM='netlify' npx netlify dev",
|
||||
"dev:node": "npx concurrently --names \"frontend,backend\" \"REACT_APP_API_ENDPOINT='http://localhost:3001/api' npx react-scripts start\" \"PLATFORM='node' DISABLE_GUI='true' PORT='3001' API_CORS_ORIGIN='*' npx nodemon server\""
|
||||
"dev:api": "DISABLE_GUI='true' PORT='3001' nodemon server",
|
||||
"dev:astro": "PUBLIC_API_ENDPOINT=http://localhost:3001/api astro dev",
|
||||
"dev": "concurrently -c magenta,cyan -n backend,frontend 'yarn dev:api' 'yarn dev:astro'"
|
||||
},
|
||||
"dependencies": {
|
||||
"@netlify/functions": "^1.6.0",
|
||||
"@sentry/react": "^7.60.0",
|
||||
"@testing-library/jest-dom": "^5.17.0",
|
||||
"@testing-library/react": "^14.0.0",
|
||||
"@testing-library/user-event": "^14.4.3",
|
||||
"@types/jest": "^29.5.3",
|
||||
"@types/node": "^20.4.4",
|
||||
"@types/react": "^18.2.15",
|
||||
"@types/react-dom": "^18.2.7",
|
||||
"@types/react-router-dom": "^5.3.3",
|
||||
"@types/react-simple-maps": "^3.0.0",
|
||||
"@types/styled-components": "^5.1.26",
|
||||
"axios": "^1.4.0",
|
||||
"@astrojs/check": "^0.5.10",
|
||||
"@astrojs/react": "^3.3.2",
|
||||
"@emotion/react": "^11.11.4",
|
||||
"@emotion/styled": "^11.11.5",
|
||||
"@fortawesome/fontawesome-svg-core": "^6.5.2",
|
||||
"@fortawesome/free-brands-svg-icons": "^6.5.2",
|
||||
"@fortawesome/free-regular-svg-icons": "^6.5.2",
|
||||
"@fortawesome/free-solid-svg-icons": "^6.5.2",
|
||||
"@fortawesome/svelte-fontawesome": "^0.2.2",
|
||||
"@types/react": "^18.3.1",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"astro": "^4.7.1",
|
||||
"axios": "^1.4.8",
|
||||
"cheerio": "^1.0.0-rc.12",
|
||||
"chrome-aws-lambda": "^10.1.0",
|
||||
"chromium": "^3.0.3",
|
||||
"connect-history-api-fallback": "^2.0.0",
|
||||
"cors": "^2.8.5",
|
||||
"csv-parser": "^3.0.0",
|
||||
"dotenv": "^16.3.1",
|
||||
"dotenv": "^16.4.5",
|
||||
"express": "^4.19.2",
|
||||
"express-rate-limit": "^7.2.0",
|
||||
"flatted": "^3.2.7",
|
||||
"follow-redirects": "^1.15.2",
|
||||
"got": "^13.0.0",
|
||||
"jest-styled-components": "^7.1.1",
|
||||
"netlify-cli": "^15.9.1",
|
||||
"perf_hooks": "^0.0.1",
|
||||
"framer-motion": "^11.2.6",
|
||||
"got": "^14.2.1",
|
||||
"pm2": "^5.3.1",
|
||||
"psl": "^1.9.0",
|
||||
"puppeteer": "^20.9.0",
|
||||
"puppeteer-core": "^21.0.3",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"puppeteer": "^22.8.0",
|
||||
"puppeteer-core": "^22.8.0",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-masonry-css": "^1.0.16",
|
||||
"react-router-dom": "^6.14.2",
|
||||
"react-scripts": "5.0.1",
|
||||
"react-router-dom": "^6.23.0",
|
||||
"react-simple-maps": "^3.0.0",
|
||||
"react-toastify": "^9.1.3",
|
||||
"recharts": "^2.7.3",
|
||||
"styled-components": "^6.0.5",
|
||||
"react-toastify": "^10.0.5",
|
||||
"recharts": "^2.12.6",
|
||||
"svelte": "^4.2.17",
|
||||
"traceroute": "^1.0.0",
|
||||
"typescript": "^5.1.6",
|
||||
"unzipper": "^0.10.14",
|
||||
"typescript": "^5.4.5",
|
||||
"unzipper": "^0.11.5",
|
||||
"url-parse": "^1.5.10",
|
||||
"wappalyzer": "^6.10.65",
|
||||
"web-vitals": "^3.4.0",
|
||||
"xml2js": "^0.6.2"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"compilerOptions": {
|
||||
"allowJs": true,
|
||||
"outDir": "./dist"
|
||||
},
|
||||
"devDependencies": {
|
||||
"serverless-domain-manager": "^7.1.1",
|
||||
"serverless-offline": "^12.0.4",
|
||||
"serverless-webpack": "^5.13.0",
|
||||
"webpack": "^5.88.2",
|
||||
"webpack-node-externals": "^3.0.0"
|
||||
"@astrojs/cloudflare": "^10.2.5",
|
||||
"@astrojs/netlify": "^5.2.0",
|
||||
"@astrojs/node": "^8.2.5",
|
||||
"@astrojs/partytown": "^2.1.0",
|
||||
"@astrojs/sitemap": "^3.1.4",
|
||||
"@astrojs/svelte": "^5.4.0",
|
||||
"@astrojs/ts-plugin": "^1.6.1",
|
||||
"@astrojs/vercel": "^7.5.4",
|
||||
"concurrently": "^8.2.2",
|
||||
"nodemon": "^3.1.0",
|
||||
"sass": "^1.77.1"
|
||||
}
|
||||
}
|
||||
|
1
public/assets/badges/dockerhub.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="205" height="20" role="img" aria-label="DockerHub: Lissy93/Web Check"><title>DockerHub: Lissy93/Web Check</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="205" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="88" height="20" fill="#1c1d28"/><rect x="88" width="117" height="20" fill="#1fb1f4"/><rect width="205" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><image x="5" y="3" width="14" height="14" xlink:href="data:image/svg+xml;base64,PHN2ZyBmaWxsPSJ3aGl0ZSIgcm9sZT0iaW1nIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHRpdGxlPkRvY2tlcjwvdGl0bGU+PHBhdGggZD0iTTEzLjk4MyAxMS4wNzhoMi4xMTlhLjE4Ni4xODYgMCAwMC4xODYtLjE4NVY5LjAwNmEuMTg2LjE4NiAwIDAwLS4xODYtLjE4NmgtMi4xMTlhLjE4NS4xODUgMCAwMC0uMTg1LjE4NXYxLjg4OGMwIC4xMDIuMDgzLjE4NS4xODUuMTg1bS0yLjk1NC01LjQzaDIuMTE4YS4xODYuMTg2IDAgMDAuMTg2LS4xODZWMy41NzRhLjE4Ni4xODYgMCAwMC0uMTg2LS4xODVoLTIuMTE4YS4xODUuMTg1IDAgMDAtLjE4NS4xODV2MS44ODhjMCAuMTAyLjA4Mi4xODUuMTg1LjE4NW0wIDIuNzE2aDIuMTE4YS4xODcuMTg3IDAgMDAuMTg2LS4xODZWNi4yOWEuMTg2LjE4NiAwIDAwLS4xODYtLjE4NWgtMi4xMThhLjE4NS4xODUgMCAwMC0uMTg1LjE4NXYxLjg4N2MwIC4xMDIuMDgyLjE4NS4xODUuMTg2bS0yLjkzIDBoMi4xMmEuMTg2LjE4NiAwIDAwLjE4NC0uMTg2VjYuMjlhLjE4NS4xODUgMCAwMC0uMTg1LS4xODVIOC4xYS4xODUuMTg1IDAgMDAtLjE4NS4xODV2MS44ODdjMCAuMTAyLjA4My4xODUuMTg1LjE4Nm0tMi45NjQgMGgyLjExOWEuMTg2LjE4NiAwIDAwLjE4NS0uMTg2VjYuMjlhLjE4NS4xODUgMCAwMC0uMTg1LS4xODVINS4xMzZhLjE4Ni4xODYgMCAwMC0uMTg2LjE4NXYxLjg4N2MwIC4xMDIuMDg0LjE4NS4xODYuMTg2bTUuODkzIDIuNzE1aDIuMTE4YS4xODYuMTg2IDAgMDAuMTg2LS4xODVWOS4wMDZhLjE4Ni4xODYgMCAwMC0uMTg2LS4xODZoLTIuMTE4YS4xODUuMTg1IDAgMDAtLjE4NS4xODV2MS44ODhjMCAuMTAyLjA4Mi4xODUuMTg1LjE4NW0tMi45MyAwaDIuMTJhLjE4NS4xODUgMCAwMC4xODQtLjE4NVY5LjAwNmEuMTg1LjE4NSAwIDAwLS4xODQtLjE4NmgtMi4xMmEuMTg1LjE4NSAwIDAwLS4xODQuMTg1djEuODg4YzAgLjEwMi4wODMuMTg1LjE4NS4xODVtLTIuOTY0IDBoMi4xMTlhLjE4NS4xODUgMCAwMC4xODUtLjE4NVY5LjAwNmEuMTg1LjE4NSAwIDAwLS4xODQtLjE4NmgtMi4xMmEuMTg2LjE4NiAwIDAwLS4xODYuMTg2djEuODg3YzAgLjEwMi4wODQuMTg1LjE4Ni4xODVtLTIuOTIgMGgyLjEyYS4xODUuMTg1IDAgMDAuMTg0LS4xODVWOS4wMDZhLjE4NS4xODUgMCAwMC0uMTg0LS4xODZoLTIuMTJhLjE4NS4xODUgMCAwMC0uMTg0LjE4NXYxLjg4OGMwIC4xMDIuMDgyLjE4NS4xODUuMTg1TTIzLjc2MyA5Ljg5Yy0uMDY1LS4wNTEtLjY3Mi0uNTEtMS45NTQtLjUxLS4zMzguMDAxLS42NzYuMDMtMS4wMS4wODctLjI0OC0xLjctMS42NTMtMi41My0xLjcxNi0yLjU2NmwtLjM0NC0uMTk5LS4yMjYuMzI3Yy0uMjg0LjQzOC0uNDkuOTIyLS42MTIgMS40My0uMjMuOTctLjA5IDEuODgyLjQwMyAyLjY2MS0uNTk1LjMzMi0xLjU1LjQxMy0xLjc0NC40MkguNzUxYS43NTEuNzUxIDAgMDAtLjc1Ljc0OCAxMS4zNzYgMTEuMzc2IDAgMDAuNjkyIDQuMDYyYy41NDUgMS40MjggMS4zNTUgMi40OCAyLjQxIDMuMTI0IDEuMTguNzIzIDMuMSAxLjEzNyA1LjI3NSAxLjEzNy45ODMuMDAzIDEuOTYzLS4wODYgMi45My0uMjY2YTEyLjI0OCAxMi4yNDggMCAwMDMuODIzLTEuMzg5Yy45OC0uNTY3IDEuODYtMS4yODggMi42MS0yLjEzNiAxLjI1Mi0xLjQxOCAxLjk5OC0yLjk5NyAyLjU1My00LjRoLjIyMWMxLjM3MiAwIDIuMjE1LS41NDkgMi42OC0xLjAwOS4zMDktLjI5My41NS0uNjUuNzA3LTEuMDQ2bC4wOTgtLjI4OFoiLz48L3N2Zz4="/><text aria-hidden="true" x="535" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="610">DockerHub</text><text x="535" y="140" transform="scale(.1)" fill="#fff" textLength="610">DockerHub</text><text aria-hidden="true" x="1455" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="1070">Lissy93/Web Check</text><text x="1455" y="140" transform="scale(.1)" fill="#fff" textLength="1070">Lissy93/Web Check</text></g></svg>
|
After Width: | Height: | Size: 3.6 KiB |
1
public/assets/badges/github.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="181" height="20" role="img" aria-label="GitHub: Lissy93/Web Check"><title>GitHub: Lissy93/Web Check</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="181" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="64" height="20" fill="#1c1d28"/><rect x="64" width="117" height="20" fill="#a832fc"/><rect width="181" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><image x="5" y="3" width="14" height="14" xlink:href="data:image/svg+xml;base64,PHN2ZyBmaWxsPSJ3aGl0ZSIgcm9sZT0iaW1nIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHRpdGxlPkdpdEh1YjwvdGl0bGU+PHBhdGggZD0iTTEyIC4yOTdjLTYuNjMgMC0xMiA1LjM3My0xMiAxMiAwIDUuMzAzIDMuNDM4IDkuOCA4LjIwNSAxMS4zODUuNi4xMTMuODItLjI1OC44Mi0uNTc3IDAtLjI4NS0uMDEtMS4wNC0uMDE1LTIuMDQtMy4zMzguNzI0LTQuMDQyLTEuNjEtNC4wNDItMS42MUM0LjQyMiAxOC4wNyAzLjYzMyAxNy43IDMuNjMzIDE3LjdjLTEuMDg3LS43NDQuMDg0LS43MjkuMDg0LS43MjkgMS4yMDUuMDg0IDEuODM4IDEuMjM2IDEuODM4IDEuMjM2IDEuMDcgMS44MzUgMi44MDkgMS4zMDUgMy40OTUuOTk4LjEwOC0uNzc2LjQxNy0xLjMwNS43Ni0xLjYwNS0yLjY2NS0uMy01LjQ2Ni0xLjMzMi01LjQ2Ni01LjkzIDAtMS4zMS40NjUtMi4zOCAxLjIzNS0zLjIyLS4xMzUtLjMwMy0uNTQtMS41MjMuMTA1LTMuMTc2IDAgMCAxLjAwNS0uMzIyIDMuMyAxLjIzLjk2LS4yNjcgMS45OC0uMzk5IDMtLjQwNSAxLjAyLjAwNiAyLjA0LjEzOCAzIC40MDUgMi4yOC0xLjU1MiAzLjI4NS0xLjIzIDMuMjg1LTEuMjMuNjQ1IDEuNjUzLjI0IDIuODczLjEyIDMuMTc2Ljc2NS44NCAxLjIzIDEuOTEgMS4yMyAzLjIyIDAgNC42MS0yLjgwNSA1LjYyNS01LjQ3NSA1LjkyLjQyLjM2LjgxIDEuMDk2LjgxIDIuMjIgMCAxLjYwNi0uMDE1IDIuODk2LS4wMTUgMy4yODYgMCAuMzE1LjIxLjY5LjgyNS41N0MyMC41NjUgMjIuMDkyIDI0IDE3LjU5MiAyNCAxMi4yOTdjMC02LjYyNy01LjM3My0xMi0xMi0xMiIvPjwvc3ZnPg=="/><text aria-hidden="true" x="415" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="370">GitHub</text><text x="415" y="140" transform="scale(.1)" fill="#fff" textLength="370">GitHub</text><text aria-hidden="true" x="1215" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="1070">Lissy93/Web Check</text><text x="1215" y="140" transform="scale(.1)" fill="#fff" textLength="1070">Lissy93/Web Check</text></g></svg>
|
After Width: | Height: | Size: 2.3 KiB |
1
public/assets/badges/sponsor.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="147" height="20" role="img" aria-label="Sponsor: Alicia Sykes"><title>Sponsor: Alicia Sykes</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="147" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="72" height="20" fill="#1c1d28"/><rect x="72" width="75" height="20" fill="#f2159a"/><rect width="147" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><image x="5" y="3" width="14" height="14" xlink:href="data:image/svg+xml;base64,PHN2ZyBmaWxsPSJ3aGl0ZSIgcm9sZT0iaW1nIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHRpdGxlPkdpdEh1YiBTcG9uc29yczwvdGl0bGU+PHBhdGggZD0iTTE3LjYyNSAxLjQ5OWMtMi4zMiAwLTQuMzU0IDEuMjAzLTUuNjI1IDMuMDMtMS4yNzEtMS44MjctMy4zMDUtMy4wMy01LjYyNS0zLjAzQzMuMTI5IDEuNDk5IDAgNC4yNTMgMCA4LjI0OWMwIDQuMjc1IDMuMDY4IDcuODQ3IDUuODI4IDEwLjIyN2EzMy4xNCAzMy4xNCAwIDAgMCA1LjYxNiAzLjg3NmwuMDI4LjAxNy4wMDguMDAzLS4wMDEuMDAzYy4xNjMuMDg1LjM0Mi4xMjYuNTIxLjEyNS4xNzkuMDAxLjM1OC0uMDQxLjUyMS0uMTI1bC0uMDAxLS4wMDMuMDA4LS4wMDMuMDI4LS4wMTdhMzMuMTQgMzMuMTQgMCAwIDAgNS42MTYtMy44NzZDMjAuOTMyIDE2LjA5NiAyNCAxMi41MjQgMjQgOC4yNDljMC0zLjk5Ni0zLjEyOS02Ljc1LTYuMzc1LTYuNzV6bS0uOTE5IDE1LjI3NWEzMC43NjYgMzAuNzY2IDAgMCAxLTQuNzAzIDMuMzE2bC0uMDA0LS4wMDItLjAwNC4wMDJhMzAuOTU1IDMwLjk1NSAwIDAgMS00LjcwMy0zLjMxNmMtMi42NzctMi4zMDctNS4wNDctNS4yOTgtNS4wNDctOC41MjMgMC0yLjc1NCAyLjEyMS00LjUgNC4xMjUtNC41IDIuMDYgMCAzLjkxNCAxLjQ3OSA0LjU0NCAzLjY4NC4xNDMuNDk1LjU5Ni43OTcgMS4wODYuNzk2LjQ5LjAwMS45NDMtLjMwMiAxLjA4NS0uNzk2LjYzLTIuMjA1IDIuNDg0LTMuNjg0IDQuNTQ0LTMuNjg0IDIuMDA0IDAgNC4xMjUgMS43NDYgNC4xMjUgNC41IDAgMy4yMjUtMi4zNyA2LjIxNi01LjA0OCA4LjUyM3oiLz48L3N2Zz4="/><text aria-hidden="true" x="455" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="450">Sponsor</text><text x="455" y="140" transform="scale(.1)" fill="#fff" textLength="450">Sponsor</text><text aria-hidden="true" x="1085" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="650">Alicia Sykes</text><text x="1085" y="140" transform="scale(.1)" fill="#fff" textLength="650">Alicia Sykes</text></g></svg>
|
After Width: | Height: | Size: 2.3 KiB |
1
public/assets/badges/webcheck.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="155" height="20" role="img" aria-label="Website: web-check.zyz"><title>Website: web-check.zyz</title><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="155" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#r)"><rect width="70" height="20" fill="#1c1d28"/><rect x="70" width="85" height="20" fill="#9fef00"/><rect width="155" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><image x="5" y="3" width="14" height="14" xlink:href="data:image/svg+xml;base64,PHN2ZyBmaWxsPSJ3aGl0ZSIgcm9sZT0iaW1nIiB2aWV3Qm94PSIwIDAgMjQgMjQiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHRpdGxlPkdvb2dsZSBDbG91ZCBTdG9yYWdlPC90aXRsZT48cGF0aCBkPSJNMjQgMi40djguNGgtMi40VjIuNEgyNHpNMCAxMC44aDIuNFYyLjRIMHY4LjR6bTMtOC40aDE4djguNEgzVjIuNHptMTIuNiA0LjJhMS44IDEuOCAwIDEgMCAzLjYgMCAxLjggMS44IDAgMCAwLTMuNiAwem0tMTAuOC42SDEyVjZINC44djEuMnptMTYuOCAxNC40SDI0di04LjRoLTIuNHY4LjR6TTAgMjEuNmgyLjR2LTguNEgwdjguNHptMy04LjRoMTh2OC40SDN2LTguNHptMTIuNiA0LjJhMS44IDEuOCAwIDEgMCAzLjYgMCAxLjggMS44IDAgMCAwLTMuNiAwek00LjggMThIMTJ2LTEuMkg0LjhWMTh6Ii8+PC9zdmc+"/><text aria-hidden="true" x="445" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="430">Website</text><text x="445" y="140" transform="scale(.1)" fill="#fff" textLength="430">Website</text><text aria-hidden="true" x="1115" y="150" fill="#ccc" fill-opacity=".3" transform="scale(.1)" textLength="750">web-check.zyz</text><text x="1115" y="140" transform="scale(.1)" fill="#333" textLength="750">webcheck.zyz</text></g></svg>
|
After Width: | Height: | Size: 1.8 KiB |
9
public/assets/images/background-dots.svg
Normal file
@ -0,0 +1,9 @@
|
||||
<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<pattern id="a" patternUnits="userSpaceOnUse" width="30" height="30">
|
||||
<rect width="100%" height="100%" fill="var(--background, #111211)" />
|
||||
<circle cx="5" cy="5" r="1.75" fill="var(--background-lighter, #3A3B3A)" opacity="0.3" />
|
||||
</pattern>
|
||||
</defs>
|
||||
<rect width="100%" height="100%" fill="url(#a)" />
|
||||
</svg>
|
After Width: | Height: | Size: 408 B |
1
public/assets/images/docker.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Docker</title><path d="M13.983 11.078h2.119a.186.186 0 00.186-.185V9.006a.186.186 0 00-.186-.186h-2.119a.185.185 0 00-.185.185v1.888c0 .102.083.185.185.185m-2.954-5.43h2.118a.186.186 0 00.186-.186V3.574a.186.186 0 00-.186-.185h-2.118a.185.185 0 00-.185.185v1.888c0 .102.082.185.185.185m0 2.716h2.118a.187.187 0 00.186-.186V6.29a.186.186 0 00-.186-.185h-2.118a.185.185 0 00-.185.185v1.887c0 .102.082.185.185.186m-2.93 0h2.12a.186.186 0 00.184-.186V6.29a.185.185 0 00-.185-.185H8.1a.185.185 0 00-.185.185v1.887c0 .102.083.185.185.186m-2.964 0h2.119a.186.186 0 00.185-.186V6.29a.185.185 0 00-.185-.185H5.136a.186.186 0 00-.186.185v1.887c0 .102.084.185.186.186m5.893 2.715h2.118a.186.186 0 00.186-.185V9.006a.186.186 0 00-.186-.186h-2.118a.185.185 0 00-.185.185v1.888c0 .102.082.185.185.185m-2.93 0h2.12a.185.185 0 00.184-.185V9.006a.185.185 0 00-.184-.186h-2.12a.185.185 0 00-.184.185v1.888c0 .102.083.185.185.185m-2.964 0h2.119a.185.185 0 00.185-.185V9.006a.185.185 0 00-.184-.186h-2.12a.186.186 0 00-.186.186v1.887c0 .102.084.185.186.185m-2.92 0h2.12a.185.185 0 00.184-.185V9.006a.185.185 0 00-.184-.186h-2.12a.185.185 0 00-.184.185v1.888c0 .102.082.185.185.185M23.763 9.89c-.065-.051-.672-.51-1.954-.51-.338.001-.676.03-1.01.087-.248-1.7-1.653-2.53-1.716-2.566l-.344-.199-.226.327c-.284.438-.49.922-.612 1.43-.23.97-.09 1.882.403 2.661-.595.332-1.55.413-1.744.42H.751a.751.751 0 00-.75.748 11.376 11.376 0 00.692 4.062c.545 1.428 1.355 2.48 2.41 3.124 1.18.723 3.1 1.137 5.275 1.137.983.003 1.963-.086 2.93-.266a12.248 12.248 0 003.823-1.389c.98-.567 1.86-1.288 2.61-2.136 1.252-1.418 1.998-2.997 2.553-4.4h.221c1.372 0 2.215-.549 2.68-1.009.309-.293.55-.65.707-1.046l.098-.288Z"/></svg>
|
After Width: | Height: | Size: 1.7 KiB |
1
public/assets/images/fly.svg
Normal file
After Width: | Height: | Size: 6.2 KiB |
1
public/assets/images/github.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>GitHub</title><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"/></svg>
|
After Width: | Height: | Size: 823 B |
1
public/assets/images/netlify.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Netlify</title><path d="M6.49 19.04h-.23L5.13 17.9v-.23l1.73-1.71h1.2l.15.15v1.2L6.5 19.04ZM5.13 6.31V6.1l1.13-1.13h.23L8.2 6.68v1.2l-.15.15h-1.2L5.13 6.31Zm9.96 9.09h-1.65l-.14-.13v-3.83c0-.68-.27-1.2-1.1-1.23-.42 0-.9 0-1.43.02l-.07.08v4.96l-.14.14H8.9l-.13-.14V8.73l.13-.14h3.7a2.6 2.6 0 0 1 2.61 2.6v4.08l-.13.14Zm-8.37-2.44H.14L0 12.82v-1.64l.14-.14h6.58l.14.14v1.64l-.14.14Zm17.14 0h-6.58l-.14-.14v-1.64l.14-.14h6.58l.14.14v1.64l-.14.14ZM11.05 6.55V1.64l.14-.14h1.65l.14.14v4.9l-.14.14h-1.65l-.14-.13Zm0 15.81v-4.9l.14-.14h1.65l.14.13v4.91l-.14.14h-1.65l-.14-.14Z"/></svg>
|
After Width: | Height: | Size: 657 B |
1
public/assets/images/swagger.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Swagger</title><path d="M12 0C5.383 0 0 5.383 0 12s5.383 12 12 12c6.616 0 12-5.383 12-12S18.616 0 12 0zm0 1.144c5.995 0 10.856 4.86 10.856 10.856 0 5.995-4.86 10.856-10.856 10.856-5.996 0-10.856-4.86-10.856-10.856C1.144 6.004 6.004 1.144 12 1.144zM8.37 5.868a6.707 6.707 0 0 0-.423.005c-.983.056-1.573.517-1.735 1.472-.115.665-.096 1.348-.143 2.017-.013.35-.05.697-.115 1.038-.134.609-.397.798-1.016.83a2.65 2.65 0 0 0-.244.042v1.463c1.126.055 1.278.452 1.37 1.629.033.429-.013.858.015 1.287.018.406.073.808.156 1.2.259 1.075 1.307 1.435 2.575 1.218v-1.283c-.203 0-.383.005-.558 0-.43-.013-.591-.12-.632-.535-.056-.535-.042-1.08-.075-1.62-.064-1.001-.175-1.988-1.153-2.625.503-.37.868-.812.983-1.398.083-.41.134-.821.166-1.237.028-.415-.023-.84.014-1.25.06-.665.102-.937.9-.91.12 0 .235-.017.369-.027v-1.31c-.16 0-.31-.004-.454-.006zm7.593.009a4.247 4.247 0 0 0-.813.06v1.274c.245 0 .434 0 .623.005.328.004.577.13.61.494.032.332.031.669.064 1.006.065.669.101 1.347.217 2.007.102.544.475.95.941 1.283-.817.549-1.057 1.333-1.098 2.215-.023.604-.037 1.213-.069 1.822-.028.554-.222.734-.78.748-.157.004-.31.018-.484.028v1.305c.327 0 .627.019.927 0 .932-.055 1.495-.507 1.68-1.412.078-.498.124-1 .138-1.504.032-.461.028-.927.074-1.384.069-.715.397-1.01 1.112-1.057a.972.972 0 0 0 .199-.046v-1.463c-.12-.014-.204-.027-.291-.032-.536-.023-.804-.203-.937-.71a5.146 5.146 0 0 1-.152-.993c-.037-.618-.033-1.241-.074-1.86-.08-1.192-.794-1.753-1.887-1.786zm-6.89 5.28a.844.844 0 0 0-.083 1.684h.055a.83.83 0 0 0 .877-.78v-.046a.845.845 0 0 0-.83-.858zm2.911 0a.808.808 0 0 0-.834.78c0 .027 0 .05.004.078 0 .503.342.826.859.826.507 0 .826-.332.826-.853-.005-.503-.342-.836-.855-.831zm2.963 0a.861.861 0 0 0-.876.835c0 .47.378.849.849.849h.009c.425.074.853-.337.881-.83.023-.457-.392-.854-.863-.854z"/></svg>
|
After Width: | Height: | Size: 1.8 KiB |
1
public/assets/images/vercel.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>Vercel</title><path d="M24 22.525H0l12-21.05 12 21.05z"/></svg>
|
After Width: | Height: | Size: 142 B |
1
public/assets/images/webauthn.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>WebAuthn</title><path d="M15.2872 3.641a8.407 8.407 0 00-8.05 7.593h.55a7.805 7.805 0 012.24-4.713 5.825 5.825 0 00.923.695c-.608 1.177-.98 2.556-1.082 4.018h.135c.105-1.467.485-2.819 1.065-3.947.745.434 1.623.754 2.577.94a27.83 27.83 0 00-.25 3.763h-.847v.135h.847c.003 1.334.09 2.617.25 3.764-.954.185-1.832.506-2.577.94a9.997 9.997 0 01-.978-3.137h-.137c.164 1.16.502 2.25.997 3.208a5.825 5.825 0 00-.924.695 7.805 7.805 0 01-2.255-4.875h-.55a8.407 8.407 0 0016.779-.675 8.398 8.398 0 00-.689-3.333 8.407 8.407 0 00-8.025-5.072zm.315.546c.155 0 .31.005.464.014.365.34.708 1.07.983 2.114a16.518 16.518 0 01.357 1.79 10.173 10.173 0 01-1.804.16 10.173 10.173 0 01-1.805-.16 16.519 16.519 0 01.357-1.79c.275-1.045.618-1.775.983-2.114a7.97 7.97 0 01.465-.014zm-.665.028c-.345.392-.658 1.093-.913 2.065a16.639 16.639 0 00-.36 1.8c-.939-.183-1.802-.498-2.533-.926.686-1.283 1.635-2.264 2.73-2.775a7.874 7.874 0 011.076-.164zm1.33 0a7.856 7.856 0 011.084.168c1.092.513 2.037 1.492 2.721 2.771-.73.428-1.594.743-2.533.927a16.64 16.64 0 00-.36-1.8c-.255-.972-.568-1.673-.912-2.066zm-2.972.314c-.655.407-1.257.989-1.776 1.73a8.166 8.166 0 00-.506.825 5.69 5.69 0 01-.89-.67 7.814 7.814 0 013.172-1.885zm4.624.006a7.862 7.862 0 013.164 1.877 5.692 5.692 0 01-.893.672 8.166 8.166 0 00-.506-.825c-.516-.738-1.115-1.318-1.765-1.724zm3.26 1.985a7.858 7.858 0 011.638 2.419 7.802 7.802 0 01.642 3.051h-2.095c-.01-1.74-.398-3.396-1.11-4.774a5.823 5.823 0 00.925-.696zm-1.044.767c.68 1.32 1.084 2.945 1.094 4.703h-3.42a27.863 27.863 0 00-.25-3.763c.953-.186 1.832-.506 2.576-.94zm-6.357.965a10.299 10.299 0 001.824.16 10.299 10.299 0 001.823-.16c.16 1.138.246 2.413.25 3.738h-1.179a1.03 1.03 0 01-.093.135h1.27a27.71 27.71 0 01-.248 3.739 10.397 10.397 0 00-3.647 0 27.733 27.733 0 01-.248-3.739h1.294a.99.99 0 01-.09-.135h-1.204c.003-1.325.088-2.6.248-3.738zm-11.22 1.129a2.585 2.585 0 00-2.547 2.35c-.142 1.541 1.064 2.842 2.566 2.842 1.26 0 2.312-.917 2.533-2.124h4.44v.972h.946v-.972h.837v1.431h.945v-2.376h-7.168a2.586 2.586 0 00-2.552-2.123zm-.058.965a1.639 1.639 0 011.707 1.637 1.64 1.64 0 01-1.639 1.638 1.639 1.639 0 01-.068-3.275zm13.09.388a.75.75 0 00-.345 1.404l-.383 1.958h1.5l-.383-1.958a.75.75 0 00.384-.654.75.75 0 00-.773-.75zm2.218 1.391h3.421c-.01 1.758-.415 3.384-1.094 4.704-.744-.434-1.623-.755-2.577-.94a27.81 27.81 0 00.25-3.764zm3.556 0h2.095a7.805 7.805 0 01-2.28 5.47 5.825 5.825 0 00-.925-.696c.712-1.378 1.1-3.033 1.11-4.774zm-5.52 3.703a10.284 10.284 0 011.562.156 16.518 16.518 0 01-.357 1.791c-.275 1.045-.618 1.774-.982 2.114a7.972 7.972 0 01-.93 0c-.365-.34-.708-1.07-.983-2.114a16.519 16.519 0 01-.357-1.79 10.284 10.284 0 012.048-.157zm1.695.181c.94.184 1.803.5 2.533.926-.686 1.284-1.635 2.265-2.73 2.776a7.874 7.874 0 01-1.075.164c.344-.393.657-1.094.913-2.065a16.64 16.64 0 00.36-1.8zm-3.874 0a16.648 16.648 0 00.36 1.8c.254.973.567 1.674.912 2.066a7.873 7.873 0 01-1.075-.164c-1.096-.511-2.045-1.492-2.73-2.775.73-.428 1.593-.743 2.533-.927zm-2.652.997a8.16 8.16 0 00.506.825c.52.741 1.121 1.323 1.776 1.73a7.814 7.814 0 01-3.174-1.884 5.694 5.694 0 01.892-.67zm9.178 0a5.694 5.694 0 01.891.67 7.814 7.814 0 01-3.173 1.885c.654-.407 1.256-.989 1.775-1.73a8.16 8.16 0 00.507-.825z"/></svg>
|
After Width: | Height: | Size: 3.2 KiB |
6
public/favicon.svg
Normal file
@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="8.424 15.685618729096989 38.844 37.92642140468227" style="max-height: 500px" width="38.844" height="37.92642140468227">
|
||||
<path stroke-linejoin="round" stroke-linecap="round" stroke-width="2.8" stroke="white" d="M43.3 30.1V20.3C43.3 19.9287 43.1525 19.5726 42.89 19.31C42.6274 19.0475 42.2713 18.9 41.9 18.9H13.9C13.5287 18.9 13.1726 19.0475 12.9101 19.31C12.6475 19.5726 12.5 19.9287 12.5 20.3V30.1C12.5 46.9 27.9 51.1 27.9 51.1C27.9 51.1 43.3 46.9 43.3 30.1Z"/>
|
||||
<path stroke-linejoin="round" stroke-linecap="round" stroke-width="2.8" stroke="#D6FB41" d="M20.8999 34.3L25.0999 38.5L34.8999 28.7"/>
|
||||
<path fill="white" d="M60.07 45.5L55.78 23.63H61.6L63.76 37.82L64.12 40.28H64.36L67.66 23.63H73.7801L77.08 40.28H77.35L77.62 38.21L79.7801 23.63H85.63L81.4001 45.5H73.72L71.1701 33.05L70.84 31.22H70.63L70.3 33.05L67.72 45.5H60.07ZM94.42 45.8C92.58 45.8 91.05 45.45 89.83 44.75C88.63 44.05 87.72 43.08 87.1 41.84C86.5 40.58 86.2 39.12 86.2 37.46V37.13C86.2 35.39 86.53 33.91 87.19 32.69C87.85 31.47 88.76 30.54 89.92 29.9C91.1 29.26 92.45 28.94 93.97 28.94C95.67 28.94 97.11 29.26 98.29 29.9C99.49 30.52 100.4 31.4 101.02 32.54C101.64 33.68 101.95 35 101.95 36.5V38.72H91.57V39.47C91.57 40.17 91.82 40.74 92.32 41.18C92.82 41.6 93.46 41.81 94.24 41.81C94.94 41.81 95.51 41.67 95.95 41.39C96.39 41.09 96.65 40.7 96.73 40.22H101.77C101.71 41.34 101.36 42.32 100.72 43.16C100.08 43.98 99.22 44.63 98.14 45.11C97.06 45.57 95.82 45.8 94.42 45.8ZM91.57 35.36V35.51H96.73V35.36C96.73 34.5 96.49 33.87 96.01 33.47C95.55 33.05 94.93 32.84 94.15 32.84C93.39 32.84 92.77 33.06 92.29 33.5C91.81 33.92 91.57 34.54 91.57 35.36ZM114.879 45.8C113.859 45.8 112.929 45.58 112.089 45.14C111.269 44.7 110.659 44.08 110.259 43.28H110.019L109.719 45.5H104.709V23.63H110.019V31.49H110.259C110.659 30.69 111.269 30.07 112.089 29.63C112.929 29.17 113.859 28.94 114.879 28.94C116.359 28.94 117.549 29.28 118.449 29.96C119.349 30.62 120.009 31.55 120.429 32.75C120.849 33.95 121.059 35.36 121.059 36.98V37.76C121.059 40.62 120.499 42.68 119.379 43.94C118.259 45.18 116.759 45.8 114.879 45.8ZM112.719 41.51C113.579 41.51 114.239 41.27 114.699 40.79C115.179 40.29 115.419 39.6 115.419 38.72V36.05C115.419 35.17 115.179 34.48 114.699 33.98C114.239 33.48 113.579 33.23 112.719 33.23C111.899 33.23 111.249 33.48 110.769 33.98C110.289 34.46 110.049 35.15 110.049 36.05V38.69C110.049 39.61 110.289 40.31 110.769 40.79C111.249 41.27 111.899 41.51 112.719 41.51Z"/>
|
||||
<path fill="#D6FB41" d="M133.77 45.8C131.61 45.8 129.77 45.41 128.25 44.63C126.73 43.83 125.56 42.71 124.74 41.27C123.94 39.83 123.54 38.15 123.54 36.23V35.96C123.54 33.38 123.99 31.15 124.89 29.27C125.79 27.37 127.1 25.91 128.82 24.89C130.54 23.85 132.61 23.33 135.03 23.33C136.99 23.33 138.71 23.67 140.19 24.35C141.67 25.01 142.83 25.94 143.67 27.14C144.51 28.34 144.96 29.75 145.02 31.37H139.17C139.05 30.41 138.59 29.64 137.79 29.06C137.01 28.48 136.02 28.19 134.82 28.19C133.4 28.19 132.27 28.52 131.43 29.18C130.59 29.82 130.05 30.83 129.81 32.21L129.24 35.36C128.94 37.1 129.21 38.47 130.05 39.47C130.89 40.45 132.13 40.94 133.77 40.94C134.99 40.94 135.97 40.69 136.71 40.19C137.47 39.67 137.97 38.97 138.21 38.09H144C143.7 39.73 143.08 41.13 142.14 42.29C141.2 43.43 140.01 44.3 138.57 44.9C137.13 45.5 135.53 45.8 133.77 45.8ZM145.633 45.5L149.503 23.63H154.873L153.553 31.19H153.883C154.343 30.49 154.973 29.95 155.773 29.57C156.593 29.17 157.463 28.97 158.383 28.97C160.283 28.97 161.693 29.62 162.613 30.92C163.553 32.2 163.813 34.02 163.393 36.38L161.773 45.5H156.373L157.963 36.47C158.163 35.41 158.063 34.6 157.663 34.04C157.263 33.48 156.603 33.2 155.683 33.2C154.843 33.2 154.173 33.47 153.673 34.01C153.173 34.53 152.843 35.22 152.683 36.08L151.063 45.5H145.633ZM173.599 45.8C171.219 45.8 169.339 45.14 167.959 43.82C166.599 42.5 165.919 40.67 165.919 38.33V38.09C165.919 36.25 166.249 34.65 166.909 33.29C167.569 31.91 168.539 30.85 169.819 30.11C171.099 29.35 172.639 28.97 174.439 28.97C176.179 28.97 177.649 29.32 178.849 30.02C180.069 30.7 180.949 31.67 181.489 32.93C182.049 34.17 182.209 35.63 181.969 37.31L181.759 38.72H171.049C171.049 38.78 171.039 38.85 171.019 38.93C171.019 38.99 171.019 39.06 171.019 39.14C170.899 39.94 171.099 40.59 171.619 41.09C172.139 41.57 172.849 41.81 173.749 41.81C174.429 41.81 174.999 41.68 175.459 41.42C175.939 41.16 176.259 40.78 176.419 40.28H181.489C181.209 41.98 180.379 43.33 178.999 44.33C177.619 45.31 175.819 45.8 173.599 45.8ZM171.679 35.21L171.619 35.51H176.989C177.049 34.63 176.849 33.97 176.389 33.53C175.949 33.07 175.299 32.84 174.439 32.84C173.579 32.84 172.929 33.07 172.489 33.53C172.049 33.97 171.779 34.53 171.679 35.21ZM191.498 45.8C189.098 45.8 187.218 45.14 185.858 43.82C184.518 42.5 183.848 40.75 183.848 38.57V38.33C183.848 36.43 184.178 34.78 184.838 33.38C185.518 31.98 186.488 30.9 187.748 30.14C189.028 29.36 190.568 28.97 192.368 28.97C194.648 28.97 196.478 29.55 197.858 30.71C199.258 31.87 199.988 33.44 200.048 35.42H194.918C194.878 34.68 194.618 34.14 194.138 33.8C193.678 33.46 193.088 33.29 192.368 33.29C191.528 33.29 190.878 33.51 190.418 33.95C189.958 34.37 189.668 34.97 189.548 35.75L189.158 38.15C188.978 39.21 189.118 40.03 189.578 40.61C190.038 41.19 190.738 41.48 191.678 41.48C192.378 41.48 192.958 41.3 193.418 40.94C193.878 40.58 194.178 40.1 194.318 39.5H199.478C199.398 40.76 199.008 41.86 198.308 42.8C197.628 43.74 196.708 44.48 195.548 45.02C194.388 45.54 193.038 45.8 191.498 45.8ZM201.092 45.5L204.932 23.63H210.332L208.232 35.42L214.622 29.27H221.222L214.052 35.69L218.402 45.5H212.552L209.852 38.96L207.212 41.27L206.462 45.5H201.092Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 5.5 KiB |
BIN
public/fonts/Hubot-Sans/Hubot-Sans.ttf
Normal file
BIN
public/fonts/Hubot-Sans/Hubot-Sans.woff2
Normal file
93
public/fonts/Hubot-Sans/LICENSE
Normal file
@ -0,0 +1,93 @@
|
||||
Copyright (c) 2022, GitHub https://github.com/github/hubot-sans
|
||||
with Reserved Font Name "Hubot Sans"
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting — in part or in whole — any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|