Commit Graph
49 Commits
Author SHA1 Message Date
asepharyana 673c934f37 test(e2e): 10min timeout for 1GB beforeAll download hook
Bun's default hook timeout (5s) killed the Hetzner 1GB download in beforeAll.
2026-08-01 20:43:00 +07:00
asepharyana 90d6c7dd6f fix(web): export showAuthScreen to window so topbar Login works
The Login button (onclick=window.showAuthScreen()) was dead — showAuthScreen
was defined but never exported via Object.assign. Also drop dead code from
the e2e suite (unused createReadStream import, unused s3StreamRequest).
2026-08-01 20:34:22 +07:00
asepharyana 2653e23283 test(e2e): auth headers on web API uploads + 1GB large-file suite
- Web API upload/delete tests now send ADMIN_API_TOKEN (POST/DELETE require auth)
- New 1GB suite: S3 single PUT, S3 multipart (40MB parts), ListObjects verify,
  POST /api/upload; skips without S3_SECRET_KEY + ADMIN_API_TOKEN
- Fix: Bun.write accepts the Response directly (dl.stream() doesn't exist)
2026-08-01 20:33:10 +07:00
asepharyana 91ec588a88 feat(web): public read-only file browser — GET API public, writes require admin
- /api/v1/* GET (list buckets/objects, download) no longer requires auth
- POST/DELETE/PUT stay behind requireAuth (upload, create/delete bucket, copy, delete object)
- FE drops blocking login screen: visitors browse + download freely
- Admin-only UI (create bucket, upload dropzone, delete, S3 creds) hidden in read-only mode
- Login button in topbar to unlock admin actions
2026-08-01 20:31:40 +07:00
asepharyana 864d41d8fc fix(nix): restrict flake to x86_64-linux (nixpkgs 26.11 dropped darwin) 2026-08-01 18:03:38 +07:00
asepharyana c14be68ff8 ci: publish flake to FlakeHub (rolling) 2026-08-01 17:58:16 +07:00
asepharyana 811a68821d ci: migrate CI to GitHub Actions (deploy nix + mirror ke Gitea backup)
Mirror to Gitea / mirror (push) Successful in 22s
Build & Deploy (Nix) / build-and-deploy (push) Failing after 35m18s
2026-08-01 16:38:58 +07:00
asepharyana bf616f6790 fix: root page 500 — resolve home.html for dev & prod layouts
Build & Deploy (Nix) / build-and-deploy (push) Successful in 54s
handleHome looked up `${import.meta.dir}/home.html` which exists in neither
layout: dev (src/interfaces/http/controllers/) nor prod bundle
($out/share/teleuploader/dist/ — flake copies home.html beside dist/).

Add resolveHomeHtml(): walk up from import.meta.dir (bounded) to find
home.html. Works for dev (src/home.html, 4 levels up) and prod
(../home.html, 1 level up). Fails fast with a clear error instead of a
bare ENOENT 500. Tests cover both layouts + not-found fallback.
2026-08-01 13:15:10 +07:00
asepharyana 24dfb1c6b1 fix: fail-fast guard TELEGRAM_CHUNK_SIZE_BYTES <= 19MB (Telegram getFile limit 20MB)
Build & Deploy (Nix) / build-and-deploy (push) Successful in 56s
Chunk parts > 19MB are stored to Telegram but getFile cannot resolve files over 20MB ('Bad Request: file is too big'), making every part undownloadable (prod bug 2026-08-01: 48MB chunk -> download 500).

- src/env.ts: reject TELEGRAM_CHUNK_SIZE_BYTES > 19922944 at startup (log error + throw), default changed 20MB -> 19MB
- src/shared/utils/validation.ts: TELEGRAM_CHUNK_SIZE_MAX_BYTES constant; asSafeChunkSize now enforces the max at runtime (covers S3 multipart parts too)
- test/env.test.ts: unit tests + subprocess fail-fast tests (48MB rejected, 19MB accepted)
- test/helpers/setup-env.ts: pin safe chunk size so a stale .env can't break the suite
- .env.example + CLAUDE.md: document the 20MB getFile limit
2026-08-01 13:06:42 +07:00
asepharyana 44e887c7cd fix: keep public upload API unauthenticated
Deploy FileDrop / deploy (push) Successful in 37s
2026-07-08 01:59:41 +07:00
asepharyana e8226bba64 ci: migrate deployment to gitea actions
Deploy FileDrop / deploy (push) Successful in 3m21s
2026-07-07 20:39:41 +07:00
asepharyana 340c12d671 feat: implement authentication routes with login, logout, and user info retrieval
feat: add S3 bucket versioning support and related XML response handling

refactor: rename temporary file paths from 'teleuploader' to 'filedrop' for consistency

fix: update Swagger documentation to reflect new API name and descriptions

test: add unit tests for authentication routes and utilities

test: implement end-to-end tests for S3 bucket configuration and versioning

chore: update environment variable defaults for new service name
2026-07-07 19:58:15 +07:00
asepharyana 144ebe6dd3 feat: implement chunked storage for Telegram file uploads and retrieval 2026-07-07 08:08:22 +07:00
asepharyana fbfff3d9ec fix: normalize web object sizes 2026-07-07 06:27:18 +07:00
asepharyana 1ef73fefa9 fix: restore multipart part order validation (without strict ETag check) 2026-07-07 06:11:49 +07:00
asepharyana bc806313b1 fix: use safe LIKE prefix matching instead of non-character range 2026-07-07 06:04:17 +07:00
asepharyana d1c8cc9d23 fix: ensure S3_DEFAULT_REGION and S3_VHOST_DOMAINS env vars are properly set in docker-compose 2026-07-07 06:02:16 +07:00
asepharyana 34962eb08a chore: update S3 vhost domains to include asepharana.web.id root/wildcard 2026-07-07 05:47:44 +07:00
asepharyana 8e6ccf2110 feat: S3 client compatibility — virtual-hosted style, CORS, presigned multi-method, ListMultipartUploads, edge case fixes
- Virtual-hosted bucket detection from Host header (extractS3BucketFromHost)
- S3 CORS headers + OPTIONS preflight + x-amz-id-2/HostId everywhere
- Presigned GET/PUT/HEAD/DELETE via centralized auth (no GET-only restriction)
- ListMultipartUploads with DB/xml helpers
- UploadPart partNumber range validation (1-10000)
- CompleteMultipartUpload ETag matching and ascending order validation
- DeleteObjects quiet mode support
- CopyObject URL-decode and conditional if-match/if-none-match
- encoding-type=url support in ListObjects V1/V2 XML
- Safe range-based prefix matching (replaces SQL LIKE)
- STREAMING-AWS4-HMAC-SHA256-PAYLOAD → 501 NotImplemented
- Traefik wildcard HostRegex for virtual-hosted style
- S3_VHOST_DOMAINS config env var
2026-07-07 05:39:23 +07:00
asepharyana 6aee3723fb fix: remove home page CSS lint warning 2026-07-07 04:48:44 +07:00
asepharyana ad3f4ce75e test: enable strict AWS SDK multipart coverage 2026-07-07 04:47:07 +07:00
asepharyana 339f788dc9 fix: ensure multipart part sizeBytes are Numbers, not DB strings 2026-07-07 04:42:07 +07:00
asepharyana 2e447ee58a fix: stream complete multipart S3 objects 2026-07-07 04:37:20 +07:00
asepharyana ad45404132 feat: support ranged S3 GetObject responses
Wire createGetObjectResponse into single-part GetObject handler for
proper Range/Content-Range support (200, 206, 416). Update presigned
E2E test to require 200. Add SDK Range request test.
2026-07-07 04:30:04 +07:00
asepharyana 378a084fd3 feat: stream S3 object bodies from Telegram parts 2026-07-07 04:25:05 +07:00
asepharyana 5253fb384d fix: verify presigned S3 URLs against public host 2026-07-07 04:21:01 +07:00
asepharyana 85aa54592a feat: add S3 byte range parser 2026-07-07 04:14:10 +07:00
asepharyana 2bf0fa5af5 docs: plan S3 compatibility completion 2026-07-07 04:03:11 +07:00
asepharyana dbdc5ed1ee docs: design remaining S3 compatibility fixes 2026-07-07 03:56:40 +07:00
asepharyana 9a48fbf227 fix: satisfy deploy lint gate for S3 compatibility work
- Apply Biome organize-import/formatting fixes across changed S3 files
- Replace remaining string concatenations with template literals for lint
- Make home page inline handlers explicit via window.* and add button types
- Clean S3 auth lint issues with dot-property access and optional chaining
- Keep GetObject proxy and production/S3 SDK tests passing

Verification:
- bun run lint (0 errors, 1 CSS specificity warning)
- S3_SECRET_KEY=<env> bun test test/production-e2e.test.ts (29 pass)
- S3_SECRET_KEY=<env> bun test test/s3-sdk.test.ts (20 pass)
- bun test test/s3-auth.test.ts (5 pass)
2026-07-07 03:07:51 +07:00
asepharyana 06f93e30f6 feat: proxy GetObject from Telegram CDN for real S3 client compatibility
- Add proxyS3Get config (PROXY_S3_GET env, default true) to env.ts
- Proxy handleGetObject and handleGetMultipartObject: fetch from Telegram
  CDN and return 200 with streaming body instead of 302 redirect
- Real S3 clients (AWS SDK v3) expect 200+body on GetObject, not redirect
- Legacy 302 redirect path preserved when proxyS3Get=false
- Updated production-e2e: GetObject asserts 200 with body content
- Updated s3-sdk.test.ts: GetObject asserts 200 with body (removed try/catch)
- Cleaned up unused multipart imports in s3-sdk.test.ts

All 49 tests pass (29 production-e2e + 20 s3-sdk).
2026-07-07 02:54:51 +07:00
asepharyana f88ac1a124 test: add real AWS SDK v3 S3 compatibility tests (20 tests)
Tests use @aws-sdk/client-s3 against https://upload.asepharyana.my.id
with forcePathStyle=true. Covers all standard S3 operations:
ListBuckets, CreateBucket, HeadBucket, DeleteBucket, PutObject,
GetObject, HeadObject, ListObjectsV1/V2 (prefix, delimiter),
CopyObject, DeleteObject, DeleteObjects (batch), error handling.

Multipart is excluded from SDK tests — the SDK adds amz-sdk-* /
x-amz-user-agent to signed headers, which can differ between
signing time and the actual request through Cloudflare, causing
403 SignatureDoesNotMatch. Multipart is verified via manual
SigV4 signing in test/production-e2e.test.ts.
2026-07-07 01:59:17 +07:00
asepharyana 57f2740df9 fix: production bugs + comprehensive production e2e tests
Fixes:
- RowList bug: postgres.js returns array directly, not {rows}. Fix in
  buckets.ts, files-ext.ts, multipart.ts (3 files, 8 functions)
- S3 ListBuckets routing: GET / was intercepted by handleHome route
- Presigned URL detection: isS3Request() only checked Authorization header
- FK constraint on bucket delete: cascade-delete files & multipart rows first
- docker-compose.yml: pass S3_ACCESS_KEY / S3_SECRET_KEY to container
- Dockerfile: copy home.html to runner stage for handleHome

Tests:
- test/production-e2e.test.ts: 29 tests (11 Web API + 18 S3 SigV4)
  All pass against https://upload.asepharyana.my.id
- Creates and cleans up real buckets/objects on production
2026-07-07 00:49:45 +07:00
asepharyana b731ddd7e1 fix: sequential test execution to avoid mock pollution between files 2026-07-06 22:50:59 +07:00
asepharyana 245138e23a Refactor code for improved readability and consistency
- Updated formatting in web-api.ts for better alignment and readability.
- Enhanced XML builders in xml.ts for clearer structure and maintainability.
- Improved test cases in s3-auth.test.ts and s3-operations.test.ts for better clarity and consistency.
- Refactored mock data in web-api.test.ts for improved readability.
2026-07-06 22:36:15 +07:00
asepharyana 2d3d7891a0 refactor: auto-run DB migration at startup, robust schema.sql path resolution 2026-07-06 22:32:06 +07:00
asepharyana 0ad783b794 fix: PutObject raw body, presigned URL auth guard, DeleteObjects tracking, home.ts path 2026-07-06 21:38:17 +07:00
asepharyana e175a27512 test: add S3 auth, operations, and web API tests 2026-07-06 21:15:26 +07:00
asepharyana 5e38f80267 feat: add web file manager UI and S3 catch-all route 2026-07-06 20:56:55 +07:00
asepharyana a4f902a37b feat: add JSON v1 web API for S3 management UI 2026-07-06 16:10:17 +07:00
asepharyana dd61e7e0fc feat: implement S3 protocol dispatcher with bucket, object, listing, and multipart operations 2026-07-06 15:52:42 +07:00
asepharyana 084ff3fb9d fix: add region validation, fix presigned URL canonical request (add method, fix headers), normalizeUri decode 2026-07-06 15:31:06 +07:00
asepharyana ee758aa939 feat: add S3 SigV4 auth verification and XML builders 2026-07-06 14:56:39 +07:00
asepharyana a2ca489039 fix: add explicit snake_case-to-camelCase mapping for S3FileRecord, add missing findOrphanFilesByBucket 2026-07-06 14:33:27 +07:00
asepharyana caef31c703 feat: add DB CRUD layer for buckets, multipart, and S3 file extensions 2026-07-06 14:23:37 +07:00
asepharyana e37fb00295 feat: add S3 env config, bucket and multipart DB schema 2026-07-06 13:59:03 +07:00
asepharyana 0d0d7a5dfa chore: remove GitHub Actions workflow for notifying parent repository 2026-07-06 01:25:37 +07:00
asepharyana 52bd704d21 refactor: enhance file handling and metrics tracking; remove unused bot health tracker 2026-07-06 01:25:18 +07:00
asepharyana bbf420759b chore: update Dockerfile and docker-compose for improved deployment process; add deploy script 2026-07-05 22:06:52 +07:00