Add proper locking/unlocking to WebDAV.

Tweak README, add one-click deploy for Digital Ocean and Render.
This commit is contained in:
Bruno Bernardino
2024-05-05 08:09:34 +01:00
parent 6ee0a56f0c
commit e21207a76a
4 changed files with 94 additions and 8 deletions

43
.do/deploy.template.yaml Normal file
View 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"

View File

@@ -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!
[![Deploy to DigitalOcean](https://www.deploytodo.com/do-btn-blue.svg)](https://cloud.digitalocean.com/apps/new?repo=https://github.com/bewcloud/bewcloud)
[![Deploy to Render](https://render.com/images/deploy-to-render-button.svg)](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
View 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

View File

@@ -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,