diff --git a/.env.example b/.env.example index fee4edc9b50cdd0e52b40847367f90dd6cb2a5f2..04d48965ea9875de6da3794f857b5a65791b6b0e 100644 --- a/.env.example +++ b/.env.example @@ -14,4 +14,4 @@ HASURA_GRAPHQL_ADMIN_SECRET=my_hasura_password HASURA_LISTEN_PORT=8765 # === GATEWAY -GATEWAY_LISTEN_PORT=3000 \ No newline at end of file +SUBMIT_GATEWAY_LISTEN_PORT=3000 \ No newline at end of file diff --git a/.env.prod.example b/.env.prod.example index 75a375e5d56b795552299b94aa4d3ae6106443b7..58b9fb5a847871d9a970e36a6b15df2248a69d6b 100644 --- a/.env.prod.example +++ b/.env.prod.example @@ -10,6 +10,7 @@ KUBO_DOMAIN=datapod.coinduf.eu KUBO_WEBSOCKET_DOMAIN=websocket.datapod.coinduf.eu KUBO_GATEWAY_DOMAIN=gateway.datapod.coinduf.eu KUBO_GATEWAY_SUBDOMAIN=pagu.re +SUBMIT_GATEWAY_LISTEN_PORT=3000 # configure the node boot DATAPOD_BOOT=bafyreih4jspnqnsd4o3sdqv7c765uyylhtlh5majjw6aq6clilkq7tmqey \ No newline at end of file diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index def34aea7a68384887e41142ced1d7775b9be4e0..6f01fa0fc856a25edb6ae8c74a2ce294091957d0 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -12,7 +12,7 @@ services: POSTGRES_PASSWORD: ${DB_PASSWORD} POSTGRES_DB: ${DB_DATABASE} healthcheck: - test: ["CMD-SHELL", "pg_isready -U ${DB_USER} -d postgres"] + test: ['CMD-SHELL', 'pg_isready -U ${DB_USER} -d postgres'] interval: 1s # ------ @@ -23,7 +23,7 @@ services: condition: service_healthy restart: always ports: - - "127.0.0.1:${HASURA_LISTEN_PORT}:8080" + - '127.0.0.1:${HASURA_LISTEN_PORT}:8080' environment: HASURA_GRAPHQL_DATABASE_URL: postgres://${DB_USER}:${DB_PASSWORD}@postgres:5432/${DB_DATABASE} HASURA_GRAPHQL_ENABLE_CONSOLE: true @@ -43,7 +43,7 @@ services: - 127.0.0.1:4002:4002 # public gateway - 127.0.0.1:${KUBO_GATEWAY_PORT}:8080 - - "[::1]:${KUBO_GATEWAY_PORT}:8080" + - '[::1]:${KUBO_GATEWAY_PORT}:8080' # expose RPC locally to allow access with ssh tunnel - 127.0.0.1:5001:5001 volumes: @@ -65,8 +65,8 @@ services: depends_on: kubo: condition: service_healthy - entrypoint: "ipfs" - command: ["--api=/dns/kubo/tcp/5001", "pubsub", "sub", "ddd"] + entrypoint: 'ipfs' + command: ['--api=/dns/kubo/tcp/5001', 'pubsub', 'sub', 'ddd'] # ------ datapod: @@ -77,14 +77,27 @@ services: kubo: condition: service_healthy environment: - KUBO_RPC: "http://kubo:5001" + KUBO_RPC: 'http://kubo:5001' DB_HOST: postgres DB_PORT: 5432 DB_USER: ${DB_USER} DB_PASSWORD: ${DB_PASSWORD} restart: always # use the datapod collector and indexer, start using given IPNS entry - command: ["./src/indexer/start.ts", "${DATAPOD_BOOT}"] + command: ['./src/indexer/start.ts', '${DATAPOD_BOOT}'] + + # ------ + gateway: + image: h30x/duniter-datapod + depends_on: + kubo: + condition: service_healthy + ports: + - ${SUBMIT_GATEWAY_LISTEN_PORT}:3000 + environment: + KUBO_RPC: 'http://kubo:5001' + restart: always + command: ['./src/gateway/start.ts'] volumes: db_data: diff --git a/src/gateway/README.md b/src/gateway/README.md index 2af5a1c0048e766302abd256062407f9c334db82..000031e6723ba6ba53f3790a0a60e2c8cc901977 100644 --- a/src/gateway/README.md +++ b/src/gateway/README.md @@ -4,4 +4,19 @@ This gateway is a way for non-p2p clients to submit data to a http endpoint that It is a stupid gateway that puts all content to local kubo node (but does not pin) and forwards the cid of the first block on pubsub topic. -Since it does not include any protection mechanism because it relies on datapod network security, it is recommanded to limit the incoming network traffic and apply IP-based protections, preventing an attacker to trigger IPFS garbage collection too easily. Or to limit connection to trusted users. \ No newline at end of file +Since it does not include any protection mechanism because it relies on datapod network security, it is recommanded to limit the incoming network traffic and apply IP-based protections, preventing an attacker to trigger IPFS garbage collection too easily. Or to limit connection to trusted users. + +## Start + +Start the gateway with: + +```sh +pnpm exec tsx ./src/gateway/start.ts +``` + +## Sumbit data + +The data submitted to the gateway should be a JSON-encoded array of strings. + +- the first string is the CID of the index request +- the other strings are base64 blocks of all data (index request, data, images...) \ No newline at end of file diff --git a/src/gateway/start.ts b/src/gateway/start.ts index 0203a4a94ed3685d03d5686f89133799a5a37a95..8610def6c2b4ff7a9d54b73f83ce85d6ca120c0f 100644 --- a/src/gateway/start.ts +++ b/src/gateway/start.ts @@ -1,9 +1,11 @@ import { TOPIC } from '../consts' import { kubo } from '../kubo' -import * as http from 'http' +import { createServer } from 'http' +import type { IncomingMessage, ServerResponse } from 'http' -// we could use this hack to allow submitting json data with html form -// https://systemoverlord.com/2016/08/24/posting-json-with-an-html-form.html +const port = process.env.SUBMIT_GATEWAY_LISTEN_PORT || 3000 +const host = '127.0.0.1' +const postgatewayUrl = `http://${host}:${port}` const GATEWAY_LANDING_PAGE = `<!DOCTYPE html> <html> <head> @@ -14,16 +16,18 @@ const GATEWAY_LANDING_PAGE = `<!DOCTYPE html> <body> <h1>Datapod Gateway</h1> <p>Use POST requests to submit data programatically. Alternatively, you can submit data manually in the form below for testing purpose.</p> - <form method="post" action="http://localhost:3000" enctype='text/plain'> + <form method="post" action="${postgatewayUrl}" enctype='text/plain'> Blocks as base64 json list: - <input type="text" name="blocks" size=100 placeholder="['index request as base64', 'data as base 64', 'optional aditionnal data as base64'...]"/> + <input type="text" name="blocks" size=100 placeholder="['index request cid', 'index request as base64', 'data as base 64', 'optional aditionnal data as base64'...]"/> <input type="submit" value="Submit" /> </form> </body> </html> ` -function handleRequest(request: http.IncomingMessage, response: http.ServerResponse<http.IncomingMessage>) { +// request handler +function handleRequest(request: IncomingMessage, response: ServerResponse<IncomingMessage>) { + // use post requests to submit data if (request.method == 'POST') { let body = '' request.on('data', function (data) { @@ -64,8 +68,6 @@ function handleRequest(request: http.IncomingMessage, response: http.ServerRespo } } -const server = http.createServer(handleRequest) -const port = process.env.GATEWAY_LISTEN_PORT || 3000 -const host = '127.0.0.1' +const server = createServer(handleRequest) server.listen(port) -console.log(`Listening on http://${host}:${port}`) +console.log(`Listening on ${postgatewayUrl}`)