diff --git a/package-lock.json b/package-lock.json index e7eb39ce..78f9d94d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "javascript-time-ago": "^2.5.11", "json-colorizer": "^3.0.1", "open": "^10.1.0", + "parse-domain": "^8.2.2", "simple-git": "^3.25.0", "string-template": "^1.0.0", "uuid": "^9.0.1" @@ -8918,6 +8919,21 @@ "node": ">=6" } }, + "node_modules/clone-regexp": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-3.0.0.tgz", + "integrity": "sha512-ujdnoq2Kxb8s3ItNBtnYeXdm07FcU0u8ARAT1lQ2YdMwQC+cdiXX8KoqMVuglztILivceTtp4ivqGSmEmhBUJw==", + "license": "MIT", + "dependencies": { + "is-regexp": "^3.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/cluster-key-slot": { "version": "1.1.2", "license": "Apache-2.0", @@ -9229,6 +9245,18 @@ "node": ">= 0.6" } }, + "node_modules/convert-hrtime": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/convert-hrtime/-/convert-hrtime-5.0.0.tgz", + "integrity": "sha512-lOETlkIeYSJWcbbcvjRKGxVMXJR+8+OQb/mTPbA4ObPMytYIsUbuOE0Jzy60hjARYszq1id0j8KgVhC+WGZVTg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/convert-source-map": { "version": "1.9.0", "dev": true, @@ -9757,6 +9785,12 @@ "node": ">=8" } }, + "node_modules/dns2": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/dns2/-/dns2-2.1.0.tgz", + "integrity": "sha512-m27K11aQalRbmUs7RLaz6aPyceLjAoqjPRNTdE7qUouQpl+PC8Bi67O+i9SuJUPbQC8dxFrczAxfmTPuTKHNkw==", + "license": "MIT" + }, "node_modules/doctrine": { "version": "3.0.0", "license": "Apache-2.0", @@ -10947,6 +10981,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/function-timeout": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/function-timeout/-/function-timeout-0.1.1.tgz", + "integrity": "sha512-0NVVC0TaP7dSTvn1yMiy6d6Q8gifzbvQafO46RtLG/kHJUBNd+pVRGOBoK44wNBvtSPUJRfdVvkFdD3p0xvyZg==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", @@ -11875,6 +11921,18 @@ "url": "https://opencollective.com/ioredis" } }, + "node_modules/ip-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-5.0.0.tgz", + "integrity": "sha512-fOCG6lhoKKakwv+C6KdsOnGvgXnmgfmp0myi3bcNwj3qfwPAxRKWEuFhvEFF7ceYIz6+1jRZ+yguLFAmUNPEfw==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ipaddr.js": { "version": "1.9.1", "license": "MIT", @@ -12015,6 +12073,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-ip": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-5.0.1.tgz", + "integrity": "sha512-FCsGHdlrOnZQcp0+XT5a+pYowf33itBalCl+7ovNXC/7o5BhIpG14M3OrpPPdBSIQJCm+0M5+9mO7S9VVTTCFw==", + "license": "MIT", + "dependencies": { + "ip-regex": "^5.0.0", + "super-regex": "^0.2.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-module": { "version": "1.0.0", "dev": true, @@ -12074,6 +12148,18 @@ "@types/estree": "*" } }, + "node_modules/is-regexp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-3.1.0.tgz", + "integrity": "sha512-rbku49cWloU5bSMI+zaRaXdQHXnthP6DZ/vLnfdSKyL4zUzuWnomtOEiZZOd+ioQ+avFo/qau3KPTc7Fjy1uPA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-stream": { "version": "2.0.1", "license": "MIT", @@ -14126,6 +14212,18 @@ "node": ">=4.0.0" } }, + "node_modules/parse-domain": { + "version": "8.2.2", + "resolved": "https://registry.npmjs.org/parse-domain/-/parse-domain-8.2.2.tgz", + "integrity": "sha512-CoksenD3UDqphCHlXIcNh/TX0dsYLHo6dSAUC/QBcJRWJXcV5rc1mwsS4WbhYGu4LD4Uxc0v3ZzGo+OHCGsLcw==", + "license": "MIT", + "dependencies": { + "is-ip": "^5.0.1" + }, + "bin": { + "parse-domain-update": "bin/update.js" + } + }, "node_modules/parse-headers": { "version": "2.0.5", "license": "MIT" @@ -15917,6 +16015,23 @@ "license": "MIT", "optional": true }, + "node_modules/super-regex": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/super-regex/-/super-regex-0.2.0.tgz", + "integrity": "sha512-WZzIx3rC1CvbMDloLsVw0lkZVKJWbrkJ0k1ghKFmcnPrW1+jWbgTkTEWVtD9lMdmI4jZEz40+naBxl1dCUhXXw==", + "license": "MIT", + "dependencies": { + "clone-regexp": "^3.0.0", + "function-timeout": "^0.1.0", + "time-span": "^5.1.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/supports-color": { "version": "5.5.0", "license": "MIT", @@ -16175,6 +16290,21 @@ "node": ">=8" } }, + "node_modules/time-span": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/time-span/-/time-span-5.1.0.tgz", + "integrity": "sha512-75voc/9G4rDIJleOo4jPvN4/YC4GRZrY8yy1uU4lwrB3XEQbWve8zXoO5No4eFrGcTAMYyoY67p8jRQdtA1HbA==", + "license": "MIT", + "dependencies": { + "convert-hrtime": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/timm": { "version": "1.7.1", "license": "MIT" @@ -17634,6 +17764,7 @@ "convertapi": "^1.15.0", "cookie-parser": "^1.4.6", "dedent": "^1.5.3", + "dns2": "^2.1.0", "express": "^4.18.2", "file-type": "^18.5.0", "firebase-admin": "^13.3.0", diff --git a/package.json b/package.json index 497e7582..0e69303c 100644 --- a/package.json +++ b/package.json @@ -54,6 +54,7 @@ "javascript-time-ago": "^2.5.11", "json-colorizer": "^3.0.1", "open": "^10.1.0", + "parse-domain": "^8.2.2", "simple-git": "^3.25.0", "string-template": "^1.0.0", "uuid": "^9.0.1" diff --git a/src/backend/src/CoreModule.js b/src/backend/src/CoreModule.js index afb67a30..1f167ec8 100644 --- a/src/backend/src/CoreModule.js +++ b/src/backend/src/CoreModule.js @@ -209,6 +209,9 @@ const install = async ({ services, app, useapi, modapi }) => { ]), }); + const { EntriService } = require('./services/EntriService.js'); + services.registerService("entri-service", EntriService) + const { InformationService } = require('./services/information/InformationService'); services.registerService('information', InformationService) @@ -398,6 +401,7 @@ const install = async ({ services, app, useapi, modapi }) => { const { WorkerService } = require('./services/worker/WorkerService'); services.registerService("worker-service", WorkerService) + const { PermissionShortcutService } = require('./services/auth/PermissionShortcutService'); services.registerService('permission-shortcut', PermissionShortcutService); } diff --git a/src/backend/src/services/EntriService.js b/src/backend/src/services/EntriService.js new file mode 100644 index 00000000..7656e1c8 --- /dev/null +++ b/src/backend/src/services/EntriService.js @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2025-present Puter Technologies Inc. + * + * This file is part of Puter. + * + * Puter is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +const BaseService = require("./BaseService"); +const fs = require("node:fs"); + +const { Entity } = require("../om/entitystorage/Entity");; +// const { get_app, subdomain } = require("../helpers"); +const { parseDomain } = require("parse-domain") + +// async function generateJWT(applicationId, secret, domain, ) { + +// return (await response.json()).auth_token; +// } + +class EntriService extends BaseService { + _init() { + + } + static IMPLEMENTS = { + ['entri']: { + async getJWT ({ domain, userHostedSite}) { + const es_subdomain = this.services.get('es:subdomain'); + let rootDomain = (parseDomain(domain)).icann.subDomains.length === 0; + const response = await fetch('https://api.goentri.com/token', { + method: 'POST', + body: JSON.stringify({ + applicationId: this.config.applicationId, + secret: this.config.secret, + domain, + dnsRecords: rootDomain ? [ + { + type: "A", + host: "@", + value: "{ENTRI_SERVERS}", //This will be automatically replaced for the Entri servers IPs + ttl: 300, + applicationUrl: userHostedSite, + } + ] : [ + { + type: "CNAME", + value: "{CNAME_TARGET}", // `{CNAME_TARGET}` will automatically use the CNAME target entered in the dashboard + host: "{SUBDOMAIN}", // This will use the user inputted subdomain. If hostRequired is set to true, then this will default to "www" + ttl: 300, + applicationUrl: userHostedSite + } + ] + }), + }); + const entity = await Entity.create({ om: es_subdomain.om }, { + subdomain: userHostedSite.replace(".puter.site", ""), + domain: "in-progress:" + domain + }); + + await es_subdomain.upsert(entity); + return { auth_token: (await response.json()).auth_token, rootDomain} + + + // let rootDomain = (parseDomain(domain)).icann.subDomains.length === 0; + + // const response = await fetch('https://api.goentri.com/power?' + new URLSearchParams({ + // domain, + // rootDomain + // }), { + // method: 'GET', + // headers: { + // 'Content-Type': 'application/json', + // 'Authorization': jwtForVerification, + // 'applicationId': this.config.applicationId + // } + // }); + + // const data = await response.json(); + // if (!data.eligible) { + // throw new APIError(); // figure this out later + // } + + + + }, + } + } + async ['__on_driver.register.interfaces']() { + const svc_registry = this.services.get('registry'); + const col_interfaces = svc_registry.get('interfaces'); + + col_interfaces.set('entri', { + description: 'Execute code with various languages.', + methods: { + getJWT: { + description: 'get JWT for entri', + parameters: { + domain: { + type: "string", + optional: false + }, + userHostedSite: { + type: "string", + optional: false + } + }, + result: { type: 'json' } + } + } + }); + } +} + +module.exports = { + EntriService, +};