Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,6 @@ npm-debug.log
# Local environment files
.env.local
.kamal/secrets*
.codex/
.playwright-mcp/
/docs/
71 changes: 71 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,77 @@ export AWS_S3_SCHEME=http://

You can also place these variables in `.env.local` at the project root. `config/runtime.exs` loads that file automatically outside the test environment without overriding shell-exported variables.

### S3 permissions and policies

There are two different pieces involved when OpenDrive uses S3:

- IAM permissions for the server-side AWS credentials
- Bucket CORS rules for browser-based direct uploads

These solve different problems and both may be required.

#### 1. Bucket CORS for direct browser uploads

If the browser uploads directly to S3 with a presigned `PUT` URL, the bucket must allow cross-origin requests from the app origin. Without this, the browser blocks the request before the object reaches S3 and the UI falls back to `/app/uploads/proxy`.

Example one-line command for local development:

```bash
aws s3api put-bucket-cors --bucket YOUR_BUCKET --cors-configuration '{"CORSRules":[{"AllowedOrigins":["http://127.0.0.1:4000","http://localhost:4000"],"AllowedMethods":["GET","HEAD","PUT"],"AllowedHeaders":["*"],"ExposeHeaders":["ETag"],"MaxAgeSeconds":3000}]}'
```

To verify:

```bash
aws s3api get-bucket-cors --bucket YOUR_BUCKET
```

Notes:

- Add any extra local or deployed origins you actually use, such as staging or production domains
- `PUT` is required for direct uploads
- `AllowedHeaders=["*"]` avoids preflight failures with presigned S3 headers

#### 2. IAM policy for the app credentials

The AWS credentials used by `OpenDrive.Storage.S3` need permission to manage the objects stored by the app. A minimal example looks like this:

```json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "OpenDriveBucketList",
"Effect": "Allow",
"Action": [
"s3:ListBucket"
],
"Resource": "arn:aws:s3:::YOUR_BUCKET"
},
{
"Sid": "OpenDriveObjectAccess",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
"s3:AbortMultipartUpload"
],
"Resource": "arn:aws:s3:::YOUR_BUCKET/*"
}
]
}
```

If you want the same IAM principal to inspect or manage bucket CORS from the CLI, add:

```json
"s3:GetBucketCORS",
"s3:PutBucketCORS"
```

on the bucket resource `arn:aws:s3:::YOUR_BUCKET`.

## Database configuration

Default database files:
Expand Down
37 changes: 37 additions & 0 deletions assets/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,43 @@
width: 172px;
}

@keyframes danger-pulse {
0%, 100% {
transform: scale(1);
box-shadow: 0 0 0 rgba(251, 113, 133, 0.12);
}

50% {
transform: scale(1.02);
box-shadow: 0 0 28px rgba(251, 113, 133, 0.18);
}
}

@keyframes deletion-sweep {
0% {
transform: translateX(-110%);
}

100% {
transform: translateX(220%);
}
}

@keyframes modal-breathe {
0%, 100% {
box-shadow:
0 32px 120px rgba(15, 23, 42, 0.55),
0 0 0 1px rgba(251, 113, 133, 0.08);
}

50% {
box-shadow:
0 36px 130px rgba(15, 23, 42, 0.62),
0 0 0 1px rgba(251, 113, 133, 0.16),
0 0 32px rgba(251, 191, 36, 0.08);
}
}

.video-preview-range::-webkit-slider-runnable-track {
height: 0.4rem;
border-radius: 9999px;
Expand Down
Loading