UNPKG

@a11ywatch/core

Version:
365 lines 17.9 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.startServer = exports.initServer = exports.killServer = exports.isReady = exports.coreServer = void 0; const fastify_1 = __importDefault(require("fastify")); const apollo_server_fastify_1 = require("apollo-server-fastify"); const node_iframe_1 = require("node-iframe"); const ws_1 = require("ws"); const ws_2 = require("graphql-ws/lib/use/ws"); const config_1 = require("./config"); const websites_1 = require("./core/controllers/websites"); const iframe_1 = require("./core/controllers/iframe"); const extracter_1 = require("./web/params/extracter"); const routes_1 = require("./core/routes"); const database_1 = require("./database"); const routes_2 = require("./web/routes"); const badge_1 = require("./web/routes/resources/badge"); const scan_1 = require("./web/routes/scan"); const github_actions_1 = require("./web/routes_groups/github-actions"); const auth_1 = require("./web/routes_groups/auth"); const init_1 = require("./proto/init"); const website_server_1 = require("./proto/website-server"); const utils_1 = require("./core/utils"); const get_user_data_1 = require("./core/utils/get-user-data"); const website_1 = require("./web/routes/data/website"); const controllers_1 = require("./core/controllers"); const crawl_1 = require("./core/streams/crawl"); const crawl_slim_1 = require("./core/streams/crawl-slim"); const apollo_server_1 = require("./apollo-server"); const event_1 = require("./event"); const update_1 = require("./core/controllers/websites/update"); const graphql_1 = require("graphql"); const main_1 = require("./core/controllers/page-speed/main"); const register_1 = require("./web/register"); const list_1 = require("./web/routes_groups/list"); const message_1 = require("./web/messages/message"); const response_1 = require("./web/response"); const web_1 = require("./web/params/web"); const add_website_1 = require("./core/controllers/websites/set/add-website"); const get_1 = require("./core/controllers/websites/find/get"); const models_1 = require("./core/models"); const limiters_1 = require("./web/limiters"); const control_1 = require("./event/emitters/control"); const dns_verify_1 = require("./web/routes_groups/dns-verify"); const sync_1 = require("./web/routes/sync"); const website_source_builder_1 = require("@a11ywatch/website-source-builder"); (0, node_iframe_1.configureAgent)(); const { GRAPHQL_PORT } = config_1.config; let coreServer; exports.coreServer = coreServer; let serverInited = false; let serverReady = false; const connectClients = () => __awaiter(void 0, void 0, void 0, function* () { yield (0, database_1.initDbConnection)(); yield (0, database_1.createPubSub)(); }); function initServer() { return __awaiter(this, void 0, void 0, function* () { let serverCleanup; const gqlServerConfig = (0, apollo_server_1.getServerConfig)({ plugins: [ { serverWillStart() { return __awaiter(this, void 0, void 0, function* () { return { drainServer() { return __awaiter(this, void 0, void 0, function* () { serverCleanup === null || serverCleanup === void 0 ? void 0 : serverCleanup.dispose(); }); }, }; }); }, }, ], }); const server = new apollo_server_fastify_1.ApolloServer(gqlServerConfig); yield server.start(); const fast = yield (0, fastify_1.default)(config_1.fastifyConfig); yield fast.register(yield server.createHandler({ cors: config_1.corsOptions })); const app = yield (0, register_1.registerApp)(fast); app.get("/status/:domain", limiters_1.limiter, badge_1.statusBadge); app.get("/api/iframe", limiters_1.limiter, iframe_1.createIframe); app.get("/api/report", limiters_1.limiter, website_1.getWebsiteReport); app.get("/api/user", (req, res) => __awaiter(this, void 0, void 0, function* () { const auth = req.headers.authorization || req.cookies.jwt; yield (0, response_1.responseWrap)(res, { callback: () => (0, get_user_data_1.retreiveUserByTokenWrapper)(auth), auth, }); })); app.get("/api/website", (req, res) => __awaiter(this, void 0, void 0, function* () { const { userId, domain, pageUrl } = (0, extracter_1.getBaseParams)(req); yield (0, response_1.responseWrap)(res, { callback: () => (0, get_1.getWebsiteWrapper)({ userId, domain, url: pageUrl, }), userId, }); })); app.get("/api/analytics", (req, res) => __awaiter(this, void 0, void 0, function* () { const { userId, domain, pageUrl } = (0, extracter_1.getBaseParams)(req); yield (0, response_1.responseWrap)(res, { callback: () => (0, controllers_1.AnalyticsController)().getWebsite({ userId, pageUrl: pageUrl ? pageUrl : undefined, domain: domain ? domain : undefined, }), userId, }); })); app.get("/api/pagespeed", (req, res) => __awaiter(this, void 0, void 0, function* () { const { userId, domain, pageUrl } = (0, extracter_1.getBaseParams)(req); yield (0, response_1.responseWrap)(res, { callback: () => (0, main_1.PageSpeedController)().getWebsite({ userId, pageUrl: pageUrl ? pageUrl : undefined, domain: domain ? domain : undefined, }), userId, }); })); app.post("/api/scan-simple", limiters_1.scanLimiter, scan_1.scanSimple); app.post("/api/scan", limiters_1.scanLimiter, scan_1.scanAuthenticated); app.post("/api/websites-sync", limiters_1.scanLimiter, sync_1.backgroundSync); app.post("/api/crawl", limiters_1.scanLimiter, crawl_1.crawlStream); app.post("/api/crawl-stream-slim", limiters_1.scanLimiter, crawl_slim_1.crawlStreamSlim); app.post(routes_1.IMAGE_CHECK, limiters_1.limiter, routes_2.detectImage); app.put("/api/website", (req, res) => __awaiter(this, void 0, void 0, function* () { var _a, _b, _c; const usr = (0, utils_1.getUserFromToken)(req.headers.authorization || req.cookies.jwt); const userId = (_a = usr === null || usr === void 0 ? void 0 : usr.payload) === null || _a === void 0 ? void 0 : _a.keyid; if (!(0, extracter_1.validateUID)(userId)) { res.status(message_1.StatusCode.Unauthorized); return res.send({ data: null, message: "Authentication required", }); } const url = (0, extracter_1.paramParser)(req, "url"); const customHeaders = (0, extracter_1.paramParser)(req, "customHeaders"); const mobile = (0, extracter_1.paramParser)(req, "mobile"); const pageInsights = (0, extracter_1.paramParser)(req, "pageInsights"); const ua = (0, extracter_1.paramParser)(req, "ua"); const standard = (0, extracter_1.paramParser)(req, "standard"); const actions = (0, extracter_1.paramParser)(req, "actions"); const subdomains = (0, extracter_1.paramParser)(req, "subdomains"); const tld = (0, extracter_1.paramParser)(req, "tld"); const ignore = (0, extracter_1.paramParser)(req, "ignore"); const rules = (0, extracter_1.paramParser)(req, "rules"); const runners = (0, extracter_1.paramParser)(req, "runners"); const proxy = (0, extracter_1.paramParser)(req, "proxy"); const sitemap = (0, extracter_1.paramParser)(req, "sitemap"); const monitoringEnabled = (0, extracter_1.paramParser)(req, "monitoringEnabled"); const actionsEnabled = (0, extracter_1.paramParser)(req, "actionsEnabled"); const { website } = yield (0, update_1.updateWebsite)({ userId, url, pageHeaders: customHeaders, mobile, pageInsights, ua, standard, actions, subdomains, tld, ignore, rules, runners, proxy: config_1.SUPER_MODE || ((_b = usr === null || usr === void 0 ? void 0 : usr.payload) === null || _b === void 0 ? void 0 : _b.audience) ? proxy : undefined, sitemap: config_1.SUPER_MODE || ((_c = usr === null || usr === void 0 ? void 0 : usr.payload) === null || _c === void 0 ? void 0 : _c.audience) ? sitemap : false, monitoringEnabled, actionsEnabled, }); return res.send({ data: website, message: "Website updated", }); })); app.post("/api/website", (req, res) => __awaiter(this, void 0, void 0, function* () { var _d; const usr = (0, utils_1.getUserFromToken)(req.headers.authorization || req.cookies.jwt); const userId = (_d = usr === null || usr === void 0 ? void 0 : usr.payload) === null || _d === void 0 ? void 0 : _d.keyid; yield (0, response_1.responseWrap)(res, { callback: () => (0, add_website_1.addWebsiteWrapper)(Object.assign({ userId, canScan: false }, (0, web_1.getWebParams)(req))), userId, }); })); app.delete("/api/website", (req, res) => __awaiter(this, void 0, void 0, function* () { var _e; const usr = (0, utils_1.getUserFromToken)(req.headers.authorization || req.cookies.jwt); const userId = (_e = usr === null || usr === void 0 ? void 0 : usr.payload) === null || _e === void 0 ? void 0 : _e.keyid; const url = (0, extracter_1.paramParser)(req, "url"); const deleteMany = (0, extracter_1.paramParser)(req, "deleteMany"); const domain = (0, extracter_1.paramParser)(req, "domain"); yield (0, response_1.responseWrap)(res, { callback: () => (0, websites_1.WebsitesController)().removeWebsite({ userId, deleteMany, url, domain, }), userId, }); })); const planInfo = { data: website_source_builder_1.priceConfig, }; app.get("/api/plans", (_, res) => { res.send(planInfo); }); const STRIPE_KEY = process.env.STRIPE_CLIENT_KEY; const stripeMessage = STRIPE_KEY ? "Set the Stripe key with stripe.js" : "Stripe key not found"; app.get("/api/client-key", (_, res) => { res.send({ data: { client_secret: STRIPE_KEY, }, message: stripeMessage, }); }); (0, dns_verify_1.setDnsVerifyRoutes)(app); (0, list_1.setListRoutes)(app); (0, auth_1.setAuthRoutes)(app); (0, github_actions_1.setGithubActionRoutes)(app); app.get(routes_1.UNSUBSCRIBE_EMAILS, routes_2.unSubEmails); app.post(routes_1.UNSUBSCRIBE_EMAILS, routes_2.unSubEmails); app.get(routes_1.CONFIRM_EMAIL, routes_2.confirmEmail); app.post(routes_1.CONFIRM_EMAIL, routes_2.confirmEmail); const hcStatus = { status: "healthy", }; app.get("/_internal_/healthcheck", (_, res) => { res.send(hcStatus); }); yield app.setErrorHandler(function (error, _request, reply) { const statusCode = (error === null || error === void 0 ? void 0 : error.statusCode) || message_1.StatusCode.Error; reply.status(statusCode).send((0, models_1.responseModel)({ code: statusCode, success: false, message: error === null || error === void 0 ? void 0 : error.message, })); }); yield app.listen(GRAPHQL_PORT, "0.0.0.0"); const subscriptionServer = new ws_1.WebSocketServer({ server: app.server, path: server.graphqlPath, }); serverCleanup = (0, ws_2.useServer)({ schema: gqlServerConfig.schema, execute: graphql_1.execute, subscribe: graphql_1.subscribe, onConnect(cnxnParams) { var _a, _b; const u = (0, utils_1.getUserFromToken)((_a = cnxnParams === null || cnxnParams === void 0 ? void 0 : cnxnParams.connectionParams) === null || _a === void 0 ? void 0 : _a.authorization); if (u) { return { userId: (_b = u === null || u === void 0 ? void 0 : u.payload) === null || _b === void 0 ? void 0 : _b.keyid, }; } return false; }, context(ctx) { var _a, _b, _c; const u = (0, utils_1.getUserFromToken)((_a = ctx === null || ctx === void 0 ? void 0 : ctx.connectionParams) === null || _a === void 0 ? void 0 : _a.authorization); return { userId: (_c = (_b = u === null || u === void 0 ? void 0 : u.payload) === null || _b === void 0 ? void 0 : _b.keyid) !== null && _c !== void 0 ? _c : -1, }; }, }, subscriptionServer); (0, config_1.logServerInit)(GRAPHQL_PORT, { graphqlPath: server.graphqlPath, }); if (process.env.A11Y_WATCH_CRON_ENABLED === "true") { const { CronJob } = yield Promise.resolve().then(() => __importStar(require("cron"))); new CronJob("0 11,23 * * *", websites_1.crawlAllAuthedWebsitesCluster).start(); } return [app.server]; }); } exports.initServer = initServer; const startServer = (disableHttp) => __awaiter(void 0, void 0, void 0, function* () { if (!serverInited) { serverInited = true; if (config_1.config.SUPER_MODE) { console.log("Application started in SUPER mode. All restrictions removed."); } (0, event_1.establishCrawlTracking)(); yield (0, database_1.initRedisConnection)(); const [_, __, [hcore]] = yield Promise.all([ connectClients(), (0, init_1.startGRPC)(), !disableHttp ? initServer() : Promise.resolve([]), ]); exports.coreServer = coreServer = hcore; serverReady = true; return new Promise((resolve) => { control_1.appEmitter.emit("event:init", true); resolve([coreServer]); }); } return Promise.resolve([]); }); exports.startServer = startServer; const isReady = () => __awaiter(void 0, void 0, void 0, function* () { return new Promise((resolve) => { if (serverReady) { resolve(true); } else { control_1.appEmitter.once("event:init", () => resolve(true)); } }); }); exports.isReady = isReady; const killServer = () => __awaiter(void 0, void 0, void 0, function* () { yield Promise.all([ coreServer === null || coreServer === void 0 ? void 0 : coreServer.close(), (0, database_1.closeDbConnection)(), (0, database_1.closeRedisConnection)(), (0, website_server_1.killServer)(), ]); serverReady = false; serverInited = false; }); exports.killServer = killServer; //# sourceMappingURL=app.js.map