diff --git a/.env.example b/.env.example index 9a8ca70..d4a52ca 100644 --- a/.env.example +++ b/.env.example @@ -1,12 +1,16 @@ ## SERVER: +# Set log verbosity [2]:integer +# 0=error <- 1=warn <- 2=info <- 3=debug +#LOGLEVEL=2 + # Port for the server [4000]:integer # (Don't expose the server to the internet) #PORT=4000 -# Set log verbosity [2]:integer -# 0=error <- 1=warn <- 2=info <- 3=debug -#LOGLEVEL=2 +# Is website served over HTTPS? [true]:boolean +#TLS=true +## DOCUMENTATION: # Enable documentation? [false]:boolean #DOCS_ENABLED=false @@ -14,11 +18,5 @@ #DOCS_PATH=/docs ## DOCUMENT: -# Enable HTTPS for document "url" parameter? [false]:boolean -#DOCUMENT_TLS=false - -# Domain for document "url" parameter [localhost]:string -#DOCUMENT_DOMAIN=localhost - # Maximum document size in kilobytes [1024]:integer #DOCUMENT_MAXSIZE=1024 \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ede2d54..817eb34 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,7 +40,7 @@ jobs: steps: - name: "Harden Runner" - uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0 + uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 with: egress-policy: audit @@ -97,7 +97,7 @@ jobs: - if: ${{ inputs.artifact-action == 'build-release' }} name: "Attest artifact" - uses: actions/attest-build-provenance@173725a1209d09b31f9d30a3890cf2757ebbff0d # v1.1.2 + uses: actions/attest-build-provenance@49df96e17e918a15956db358890b08e61c704919 # v1.2.0 with: subject-path: | dist/*.tar.gz @@ -117,7 +117,7 @@ jobs: steps: - name: "Harden Runner" - uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0 + uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 with: egress-policy: audit @@ -180,7 +180,7 @@ jobs: - if: ${{ inputs.image-action == 'build-release' }} name: "Attest image" - uses: actions/attest-build-provenance@173725a1209d09b31f9d30a3890cf2757ebbff0d # v1.1.2 + uses: actions/attest-build-provenance@49df96e17e918a15956db358890b08e61c704919 # v1.2.0 with: subject-name: "${{ env.REGISTRY }}/${{ steps.build-image.outputs.image }}" subject-digest: ${{ steps.push-image.outputs.digest }} diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml index ab17c9c..9313c42 100644 --- a/.github/workflows/security.yml +++ b/.github/workflows/security.yml @@ -35,7 +35,7 @@ jobs: steps: - name: "Harden Runner" - uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0 + uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 with: egress-policy: audit @@ -45,12 +45,12 @@ jobs: persist-credentials: false - name: "Setup CodeQL" - uses: github/codeql-action/init@f079b8493333aace61c81488f8bd40919487bd9f # v3.25.7 + uses: github/codeql-action/init@2e230e8fe0ad3a14a340ad0815ddb96d599d2aff # v3.25.8 with: languages: ${{ matrix.language }} - name: "Run analysis" - uses: github/codeql-action/analyze@f079b8493333aace61c81488f8bd40919487bd9f # v3.25.7 + uses: github/codeql-action/analyze@2e230e8fe0ad3a14a340ad0815ddb96d599d2aff # v3.25.8 with: category: "/language:${{ matrix.language }}" @@ -63,7 +63,7 @@ jobs: steps: - name: "Harden Runner" - uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0 + uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 with: egress-policy: audit @@ -80,6 +80,6 @@ jobs: publish_results: true - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@f079b8493333aace61c81488f8bd40919487bd9f # v3.25.7 + uses: github/codeql-action/upload-sarif@2e230e8fe0ad3a14a340ad0815ddb96d599d2aff # v3.25.8 with: sarif_file: scoreboard.sarif diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c3401db..63299e4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -28,7 +28,7 @@ jobs: runs-on: ubuntu-latest steps: - name: "Harden Runner" - uses: step-security/harden-runner@f086349bfa2bd1361f7909c78558e816508cdc10 # v2.8.0 + uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1 with: egress-policy: audit diff --git a/README.md b/README.md index 8248621..000291a 100644 --- a/README.md +++ b/README.md @@ -7,23 +7,34 @@ ### Binaries -- Download latest release: +- Download the [latest release](https://github.com/jspaste/backend/releases/latest) - Uncompress to a new folder - Modify the `.env.example` file to your needs and rename it to `.env` -- Execute the binary +- Execute the binary... -### Containerized +Windows: + +```powershell +powershell -c ".\backend.exe" +``` + +Linux & macOS: + +```shell +chmod +x ./backend +./backend +``` + +### Container - Pull latest image: `docker pull ghcr.io/jspaste/backend:latest` - Run container: `docker run -e DOCS_ENABLED=true -d -p 127.0.0.1:4000:4000 ghcr.io/jspaste/backend:latest` ## Validate -All artifacts and images originate from this repository (), no other artifacts or -images built and distributed outside of this repository are considered secure nor trusted by the JSPaste developers. - -You can verify the integrity and origin of an artifact and/or image using the GitHub CLI or manually -at [JSPaste Attestations](https://github.com/jspaste/backend/attestations). +> [!IMPORTANT] +> ALL artifacts and images originate from [this](https://github.com/jspaste/backend) repository, no other artifacts or +> images built and distributed outside that repository are considered secure nor trusted by the JSPaste developers. Artifacts are attested and can be verified using the following command: @@ -32,13 +43,18 @@ gh attestation verify backend.tar.gz \ --owner JSPaste ``` -Since container version `2024.05.06-e105023`, images are attested and can be verified using the following command: +Since container +version [`2024.05.06-e105023`](https://github.com/orgs/jspaste/packages/container/backend/212635273?tag=2024.05.06-e105023), +images are attested and can be verified using the following command: ```shell gh attestation verify oci://ghcr.io/jspaste/backend:latest \ --owner JSPaste ``` +You can verify the integrity and origin of an artifact and/or image using the GitHub CLI or manually +at [JSPaste Attestations](https://github.com/jspaste/backend/attestations). + ## License This project is licensed under the EUPL License. See the [`LICENSE`](LICENSE) file for more details. diff --git a/biome.json b/biome.json index f06510f..6b521d5 100644 --- a/biome.json +++ b/biome.json @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/1.7.3/schema.json", + "$schema": "https://biomejs.dev/schemas/1.8.1/schema.json", "files": { "ignore": ["**/node_modules/", "documents/", "dist/"], "ignoreUnknown": true @@ -22,7 +22,7 @@ "quoteProperties": "asNeeded", "quoteStyle": "single", "semicolons": "always", - "trailingComma": "none" + "trailingCommas": "none" } }, "json": { diff --git a/bun.lockb b/bun.lockb index 6817d2d..60b123d 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 2615731..facdc8f 100644 --- a/package.json +++ b/package.json @@ -13,27 +13,27 @@ "build:standalone:linux-arm64": "bun run build:standalone -- --target=bun-linux-arm64", "build:standalone:windows-amd64": "bun run build:standalone -- --target=bun-windows-x64-modern", "fix": "bun run fix:biome && bun run fix:package", - "fix:biome": "bun biome check --apply .", + "fix:biome": "bun biome check --write", "fix:package": "bun sort-package-json --quiet", "lint": "bun run lint:biome && bun run lint:tsc", - "lint:biome": "bun biome lint .", + "lint:biome": "bun biome lint", "lint:tsc": "bun tsc --noEmit", "start": "bun run build -- --sourcemap && bun ./dist/backend.js", "start:dev": "bun ./src/index.ts" }, "dependencies": { - "@hono/zod-openapi": "~0.14.1", + "@hono/zod-openapi": "~0.14.2", "@scalar/hono-api-reference": "~0.5.62", "@types/bun": "~1.1.3", "cbor-x": "~1.5.9", "chalk": "~5.3.0", "env-var": "~7.5.0", - "hono": "~4.4.3", + "hono": "~4.4.5", "loglevel": "~1.9.1", "typescript": "~5.4.5" }, "devDependencies": { - "@biomejs/biome": "~1.7.3", + "@biomejs/biome": "~1.8.1", "lefthook": "~1.6.15", "sort-package-json": "~2.10.0" }, diff --git a/src/endpoints/v2/access.route.ts b/src/endpoints/v2/access.route.ts index 8dac7cb..55f9d30 100644 --- a/src/endpoints/v2/access.route.ts +++ b/src/endpoints/v2/access.route.ts @@ -86,7 +86,7 @@ export const accessRoute = (endpoint: OpenAPIHono): void => { return ctx.json({ key: params.name, data: buffer.toString('binary'), - url: config.hostname.concat('/', params.name), + url: config.protocol.concat(new URL(ctx.req.url).host.concat('/', params.name)), expirationTimestamp: 0 }); }, diff --git a/src/endpoints/v2/publish.route.ts b/src/endpoints/v2/publish.route.ts index 9b3223a..264c189 100644 --- a/src/endpoints/v2/publish.route.ts +++ b/src/endpoints/v2/publish.route.ts @@ -129,7 +129,7 @@ export const publishRoute = (endpoint: OpenAPIHono): void => { return ctx.json({ key: name, secret: secret, - url: config.hostname.concat('/', name), + url: config.protocol.concat(new URL(ctx.req.url).host.concat('/', name)), expirationTimestamp: 0 }); }, diff --git a/src/index.ts b/src/index.ts index 7f230f2..3769a96 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,8 @@ import { env, server } from './server.ts'; +// TODO: Support graceful shutdown +process.on('SIGTERM', () => process.exit(0)); + export default { port: env.port, fetch: server().fetch diff --git a/src/server.ts b/src/server.ts index 295b96d..164022e 100644 --- a/src/server.ts +++ b/src/server.ts @@ -11,15 +11,14 @@ import { ErrorCode } from './types/ErrorHandler.ts'; export const env = { port: envvar('PORT').default(4000).asPortNumber(), logLevel: envvar('LOGLEVEL').default(2).asIntPositive(), - documentTLS: envvar('DOCUMENT_TLS').asBoolStrict() ?? false, - documentDomain: envvar('DOCUMENT_DOMAIN').default('localhost').asString(), + tls: envvar('TLS').asBoolStrict() ?? true, documentMaxSize: envvar('DOCUMENT_MAXSIZE').default(1024).asIntPositive(), docsEnabled: envvar('DOCS_ENABLED').asBoolStrict() ?? false, docsPath: envvar('DOCS_PATH').default('/docs').asString() } as const; export const config = { - hostname: (env.documentTLS ? 'https://' : 'http://').concat(env.documentDomain), + protocol: env.tls ? 'https://' : 'http://', apiPath: '/api', storagePath: 'documents/', documentNameLengthMin: 2, diff --git a/src/server/documentation.ts b/src/server/documentation.ts index 96ace8a..d214b1b 100644 --- a/src/server/documentation.ts +++ b/src/server/documentation.ts @@ -16,11 +16,11 @@ export const documentation = (instance: OpenAPIHono): void => { }, servers: [ { - url: new URL(ctx.req.url).origin, + url: config.protocol.concat(new URL(ctx.req.url).host), description: 'This instance' }, { - url: new URL(ctx.req.url).origin.concat(config.apiPath), + url: config.protocol.concat(new URL(ctx.req.url).host.concat(config.apiPath)), description: 'This instance workaround (See https://github.com/honojs/middleware/issues/459)' }, {