129 lines
7.5 KiB
Markdown
129 lines
7.5 KiB
Markdown
# Dodo Transfer
|
|
|
|
사내에서 쓰는 셀프 호스팅 파일 전달 서비스입니다. 파일을 올리면 링크가 만들어지고, 받는 사람은 링크로 내려받습니다.
|
|
계정 없이 쓰고, 비밀번호와 보관 기간으로 접근을 관리합니다.
|
|
|
|
[PsiTransfer](https://github.com/psi-4ward/psitransfer)(BSD-2-Clause)를 바탕으로 화면과 동작을 새로 만들었습니다.
|
|
[출처와 라이선스](#출처와-라이선스)를 보세요.
|
|
|
|
## 기능
|
|
|
|
**올리는 사람**
|
|
|
|
* 파일을 화면 어디에든 끌어다 놓거나, 붙여넣기(Ctrl+V)로 추가하고, 올리기 전에 썸네일과 미리보기로 확인
|
|
* 큰 파일도 조각으로 나누어 올리고, 연결이 끊기면 이어서 올림 ([tus](https://tus.io))
|
|
* 보관 기간: 1회 다운로드 / 1일 / 3일 / 5일 / 7일 버튼, 그 외는 목록에서 선택
|
|
* 비밀번호는 필수 (1회 다운로드만 예외). 무작위 비밀번호 생성 버튼
|
|
* **"인증된 사용자는 비밀번호 없이 다운로드"**: 업로드 로그인 상태인 사내 사용자는 링크를 열 때 비밀번호를 묻지 않고,
|
|
외부 수신자는 비밀번호를 입력
|
|
* 완료 후 "링크와 비밀번호 복사", QR 코드, 이메일 버튼
|
|
* "내 업로드": 이 브라우저에서 올린 링크를 다시 보기 (비밀번호는 저장하지 않음)
|
|
* 업로드 로그인은 한 번 하면 7일 유지되고, 사용할 때마다 연장
|
|
|
|
**받는 사람**
|
|
|
|
* 만료일과 남은 시간 표시, 파일별 다운로드와 전체 받기(zip, tar.gz)
|
|
* 브라우저가 표시할 수 있는 파일(이미지, PDF, 동영상, 오디오, 텍스트·코드)은 목록의 썸네일과 모달 미리보기로 확인
|
|
(새 창을 열지 않음). 미리보기는 다운로드로 집계되지 않음
|
|
* 1회 다운로드: 한 번 받으면 삭제됨. 미리보기와 썸네일은 제공하지 않음
|
|
|
|
**관리자** (`/admin`)
|
|
|
|
* 올라온 파일 조회, 검색, 정렬, 미리보기, 다운로드, 삭제 (파일 단위, bucket 단위)
|
|
* 서비스 이름, 로고, 하단 저작권 표기 변경 (저장하면 모든 화면에 바로 적용)
|
|
|
|
그 밖에: 라이트/다크 모드(브라우저 설정을 따름), 모바일 화면, 다국어(기본 한국어와 영어, 브라우저 언어를 따름),
|
|
웹훅, 도커 상태 확인(`/healthz`).
|
|
|
|
## 빠르게 시작하기
|
|
|
|
도커를 권장합니다. 자세한 내용은 [docs/deployment-docker.md](docs/deployment-docker.md)를 보세요.
|
|
|
|
```bash
|
|
git clone https://git.dodo-lab.kr/blue2rai/DodoTransfer.git
|
|
cd DodoTransfer
|
|
cp .env.example .env # 관리자와 업로드 비밀번호를 정합니다
|
|
docker compose -f compose.example.yaml up -d --build
|
|
```
|
|
|
|
`http://localhost:3377/sharing/`에 접속합니다 (예시 compose는 `/sharing` 하위 경로로 서비스합니다).
|
|
|
|
데이터는 컨테이너의 `/data` 볼륨에 저장됩니다. 업로드한 파일과 관리자 설정(이름, 로고)이 모두 여기에 있으므로,
|
|
이 볼륨만 유지하면 컨테이너를 다시 만들어도 모두 그대로입니다.
|
|
|
|
## 설정
|
|
|
|
모든 설정은 `PSITRANSFER_` 접두사의 환경변수로 바꿀 수 있습니다. 자주 쓰는 것은 다음과 같습니다.
|
|
전체 목록은 [docs/configuration.md](docs/configuration.md)에 있습니다.
|
|
|
|
| 환경변수 | 설명 |
|
|
|---|---|
|
|
| `PSITRANSFER_UPLOAD_PASS` | 업로드 비밀번호. 없으면 누구나 올릴 수 있음 |
|
|
| `PSITRANSFER_ADMIN_PASS` | 관리자 비밀번호. 없으면 `/admin`이 없음 |
|
|
| `PSITRANSFER_BASE_URL` | 하위 경로로 서비스할 때 (`/sharing`) |
|
|
| `PSITRANSFER_RETENTIONS` | 보관 기간 목록 (JSON) |
|
|
| `PSITRANSFER_QUICK_RETENTIONS` | 버튼으로 보일 보관 기간 (쉼표로 구분) |
|
|
| `PSITRANSFER_DEFAULT_RETENTION` | 처음 선택돼 있는 보관 기간 (초) |
|
|
| `PSITRANSFER_REQUIRE_BUCKET_PASSWORD` | 비밀번호 필수 여부 (기본 `true`, 1회 다운로드는 예외) |
|
|
| `PSITRANSFER_MAX_AGE` | 어떤 파일도 이 시간(초)이 지나면 삭제 |
|
|
| `PSITRANSFER_MAX_FILE_SIZE`, `PSITRANSFER_MAX_BUCKET_SIZE` | 크기 제한 (바이트) |
|
|
| `PSITRANSFER_TRUST_PROXY` | 리버스 프록시 뒤에서 실제 IP를 로그에 남김 |
|
|
| `PSITRANSFER_APP_NAME` | 서비스 이름의 기본값 (관리자 설정이 우선) |
|
|
|
|
## 이름과 로고
|
|
|
|
기본은 `Dodo Transfer`와 임의로 만든 도도새 아이콘입니다. 관리자 페이지(`/admin` > 설정)에서 이름, 로고, 하단
|
|
표기를 바꿀 수 있고, 코드를 고치거나 다시 빌드할 필요가 없습니다. 아진산업 로고 파일은
|
|
[docs/brand/ajin-logo.png](docs/brand/ajin-logo.png)에 있습니다. 자세한 내용은
|
|
[docs/layout-customization.md](docs/layout-customization.md)를 보세요.
|
|
|
|
## 로그인과 보안
|
|
|
|
* **업로드 로그인:** 업로드 비밀번호로 로그인하면 서버가 서명된 토큰을 발급해 브라우저에 보관합니다. 비밀번호는 저장하지
|
|
않고, 서버에도 로그인 상태를 저장하지 않으므로 컨테이너를 다시 시작해도 유지됩니다. 업로드나 관리자 비밀번호를 바꾸면
|
|
모든 토큰이 무효가 됩니다.
|
|
* **bucket 비밀번호:** 서버에는 argon2 해시로만 저장됩니다.
|
|
* **파일 주소:** `files/<bucket>++<무작위 UUID>` 형태이고, 목록을 받을 때(비밀번호 확인 후)만 알 수 있습니다.
|
|
* **미리보기:** 서버가 파일 이름의 확장자로 형식을 정하고 허용 목록에 있는 것만 인라인으로 내려줍니다 (HTML은 제외).
|
|
스크립트가 실행되지 않도록 응답에 `sandbox` CSP와 `nosniff`를 붙입니다.
|
|
* **관리자 다운로드:** 비밀번호 헤더를 보낼 수 없는 일반 링크 대신 60초 동안만 유효한 서명 링크를 씁니다.
|
|
* **종단 간 암호화는 없습니다.** 전송 구간 암호화는 nginx의 HTTPS로 처리하세요 ([예시](docs/nginx-ssl-example.conf)).
|
|
|
|
## 개발
|
|
|
|
Node.js 24 이상이 필요합니다.
|
|
|
|
```bash
|
|
npm ci # 서버 의존성
|
|
npm --prefix app ci # 프론트엔드 의존성
|
|
npm run build # app/src를 public/app으로 빌드
|
|
NODE_ENV=dev npm run dev # 개발 서버 (config.dev.js 사용, 관리자 비밀번호 admin)
|
|
|
|
npm test # 단위 테스트와 통합 테스트
|
|
```
|
|
|
|
| 위치 | 내용 |
|
|
|---|---|
|
|
| `app.js`, `config.js` | 시작과 설정 |
|
|
| `lib/endpoints.js` | 화면 껍데기, 다운로드, 업로드 라우트 |
|
|
| `lib/admin.js` | 관리자 API (파일 관리, 설정) |
|
|
| `lib/auth.js`, `lib/settings.js`, `lib/mime.js` | 로그인 토큰, 이름과 로고 설정, 미리보기 형식 |
|
|
| `lib/db.js`, `lib/store.js`, `lib/tusboy/` | 파일 인덱스와 만료, 저장소, tus 업로드 |
|
|
| `app/` | 프론트엔드 (Vue 3, Vite, Pinia) |
|
|
| `lang/` | 화면 문구 (`en.js`가 기본, `ko.js`가 한국어) |
|
|
| `plugins/` | 웹훅 |
|
|
| `docs/` | 문서, 설계 기록(`DESIGN.md`), 디자인 목업(`mockup/`) |
|
|
|
|
디버그 로그는 `DEBUG=psitransfer:* npm start`로 볼 수 있습니다.
|
|
|
|
## 참고
|
|
|
|
* 전체 받기(zip, tar.gz)는 이어받기를 지원하지 않습니다. 파일 하나씩 받으면 이어받기가 됩니다.
|
|
* 동영상과 오디오는 코덱에 따라 브라우저에서 재생되지 않을 수 있습니다 (예: H.265). 그때는 다운로드를 안내합니다.
|
|
* 예전 PsiTransfer가 저장한 `/data`는 그대로 쓸 수 있습니다. 이전 파일에는 썸네일이 없어 아이콘으로 표시됩니다.
|
|
|
|
## 출처와 라이선스
|
|
|
|
이 프로젝트는 Christoph Wiechert의 [PsiTransfer](https://github.com/psi-4ward/psitransfer)를 바탕으로 합니다.
|
|
원본의 라이선스(BSD 2-Clause)와 저작권 고지는 [LICENSE](LICENSE)에 그대로 유지합니다.
|