Add proper locking/unlocking to WebDAV.
Tweak README, add one-click deploy for Digital Ocean and Render.
This commit is contained in:
43
.do/deploy.template.yaml
Normal file
43
.do/deploy.template.yaml
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
spec:
|
||||||
|
name: bewcloud
|
||||||
|
envs:
|
||||||
|
- key: BASE_URL
|
||||||
|
scope: RUN_AND_BUILD_TIME
|
||||||
|
value: ${app.PUBLIC_URL}
|
||||||
|
services:
|
||||||
|
- name: app
|
||||||
|
dockerfile_path: Dockerfile
|
||||||
|
git:
|
||||||
|
branch: main
|
||||||
|
http_port: 8000
|
||||||
|
instance_count: 1
|
||||||
|
instance_size_slug: basic-xs
|
||||||
|
routes:
|
||||||
|
- path: /
|
||||||
|
health_check:
|
||||||
|
http_path: /
|
||||||
|
source_dir: /
|
||||||
|
envs:
|
||||||
|
- key: POSTGRESQL_HOST
|
||||||
|
scope: RUN_AND_BUILD_TIME
|
||||||
|
value: ${db.HOSTNAME}
|
||||||
|
- key: POSTGRESQL_USER
|
||||||
|
scope: RUN_AND_BUILD_TIME
|
||||||
|
value: ${db.USERNAME}
|
||||||
|
- key: POSTGRESQL_PASSWORD
|
||||||
|
scope: RUN_AND_BUILD_TIME
|
||||||
|
value: ${db.PASSWORD}
|
||||||
|
- key: POSTGRESQL_DBNAME
|
||||||
|
scope: RUN_AND_BUILD_TIME
|
||||||
|
value: ${db.DATABASE}
|
||||||
|
- key: POSTGRESQL_PORT
|
||||||
|
scope: RUN_AND_BUILD_TIME
|
||||||
|
value: ${db.PORT}
|
||||||
|
- key: POSTGRESQL_CAFILE
|
||||||
|
scope: RUN_AND_BUILD_TIME
|
||||||
|
value: ""
|
||||||
|
databases:
|
||||||
|
- name: db
|
||||||
|
engine: PG
|
||||||
|
production: false
|
||||||
|
version: "15"
|
||||||
13
README.md
13
README.md
@@ -8,11 +8,14 @@ If you're looking for the desktop sync app, it's at [`bewcloud-desktop`](https:/
|
|||||||
|
|
||||||
If you're looking for the mobile app, it's at [`bewcloud-mobile`](https://github.com/bewcloud/bewcloud-mobile).
|
If you're looking for the mobile app, it's at [`bewcloud-mobile`](https://github.com/bewcloud/bewcloud-mobile).
|
||||||
|
|
||||||
> [!CAUTION]
|
|
||||||
> This is actively being built and should be considered pre-alpha. Bugs will exist. Code and models _can_ change without a good upgrade path (though I'll try to avoid that). **Don't use it as your only source of data!**
|
|
||||||
|
|
||||||
## Self-host it!
|
## Self-host it!
|
||||||
|
|
||||||
|
[](https://cloud.digitalocean.com/apps/new?repo=https://github.com/bewcloud/bewcloud)
|
||||||
|
|
||||||
|
[](https://render.com/deploy?repo=https://github.com/bewcloud/bewcloud)
|
||||||
|
|
||||||
|
Or on your own machine:
|
||||||
|
|
||||||
Download/copy [`docker-compose.yml`](/docker-compose.yml) and [`.env.sample`](/.env.sample) as `.env`.
|
Download/copy [`docker-compose.yml`](/docker-compose.yml) and [`.env.sample`](/.env.sample) as `.env`.
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
@@ -54,8 +57,8 @@ $ make build # generates all static files for production deploy
|
|||||||
|
|
||||||
- Routes defined at `routes/`.
|
- Routes defined at `routes/`.
|
||||||
- Static files are defined at `static/`.
|
- Static files are defined at `static/`.
|
||||||
- Static frontend components are defined at `components/`.
|
- Frontend-only components are defined at `components/`.
|
||||||
- Interactive frontend components are defined at `islands/`.
|
- Isomorphic components are defined at `islands/`.
|
||||||
- Cron jobs are defined at `crons/`.
|
- Cron jobs are defined at `crons/`.
|
||||||
- Reusable bits of code are defined at `lib/`.
|
- Reusable bits of code are defined at `lib/`.
|
||||||
- Database migrations are defined at `db-migrations/`.
|
- Database migrations are defined at `db-migrations/`.
|
||||||
|
|||||||
36
render.yaml
Normal file
36
render.yaml
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
services:
|
||||||
|
- type: web
|
||||||
|
name: bewcloud
|
||||||
|
env: docker
|
||||||
|
plan: starter
|
||||||
|
healthCheckPath: /
|
||||||
|
envVars:
|
||||||
|
- key: BASE_URL
|
||||||
|
fromService:
|
||||||
|
name: bewcloud
|
||||||
|
type: web
|
||||||
|
property: host
|
||||||
|
- key: POSTGRESQL_HOST
|
||||||
|
fromDatabase:
|
||||||
|
name: bewcloud
|
||||||
|
property: host
|
||||||
|
- key: POSTGRESQL_USER
|
||||||
|
fromDatabase:
|
||||||
|
name: bewcloud
|
||||||
|
property: user
|
||||||
|
- key: POSTGRESQL_PASSWORD
|
||||||
|
fromDatabase:
|
||||||
|
name: bewcloud
|
||||||
|
property: password
|
||||||
|
- key: POSTGRESQL_DBNAME
|
||||||
|
fromDatabase:
|
||||||
|
name: bewcloud
|
||||||
|
property: database
|
||||||
|
- key: POSTGRESQL_PORT
|
||||||
|
fromDatabase:
|
||||||
|
name: bewcloud
|
||||||
|
property: port
|
||||||
|
|
||||||
|
databases:
|
||||||
|
- name: bewcloud
|
||||||
|
plan: starter
|
||||||
@@ -4,6 +4,7 @@ import { parse, stringify } from 'xml';
|
|||||||
|
|
||||||
import { FreshContextState } from '/lib/types.ts';
|
import { FreshContextState } from '/lib/types.ts';
|
||||||
import { getFilesRootPath } from '/lib/config.ts';
|
import { getFilesRootPath } from '/lib/config.ts';
|
||||||
|
import Locker from '/lib/interfaces/locker.ts';
|
||||||
import {
|
import {
|
||||||
addDavPrefixToKeys,
|
addDavPrefixToKeys,
|
||||||
buildPropFindResponse,
|
buildPropFindResponse,
|
||||||
@@ -148,8 +149,10 @@ export const handler: Handler<Data, FreshContextState> = async (request, context
|
|||||||
const xml = await request.clone().text();
|
const xml = await request.clone().text();
|
||||||
const parsedXml = parse(xml) as Record<string, any>;
|
const parsedXml = parse(xml) as Record<string, any>;
|
||||||
|
|
||||||
// TODO: This should create an actual lock, not just "pretend", and have it checked when fetching a directory/file
|
|
||||||
const lockToken = crypto.randomUUID();
|
const lockToken = crypto.randomUUID();
|
||||||
|
const lock = new Locker(`dav:${lockToken}`);
|
||||||
|
|
||||||
|
await lock.acquire();
|
||||||
|
|
||||||
const responseXml: Record<string, any> = {
|
const responseXml: Record<string, any> = {
|
||||||
xml: {
|
xml: {
|
||||||
@@ -188,8 +191,9 @@ export const handler: Handler<Data, FreshContextState> = async (request, context
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (request.method === 'UNLOCK') {
|
if (request.method === 'UNLOCK') {
|
||||||
// TODO: This should release an actual lock, not just "pretend"
|
const lockToken = request.headers.get('Lock-Token');
|
||||||
// const lockToken = request.headers.get('Lock-Token');
|
const lock = new Locker(`dav:${lockToken}`);
|
||||||
|
lock.release();
|
||||||
|
|
||||||
return new Response(null, {
|
return new Response(null, {
|
||||||
status: 204,
|
status: 204,
|
||||||
|
|||||||
Reference in New Issue
Block a user