Commit Graph

124 Commits

Author SHA1 Message Date
giles
40b010b8d9 Disable CI — moved to coop/art-dag monorepo 2026-02-24 23:24:39 +00:00
giles
79caa24e21 Add coop internal URL env vars to L2 docker-compose
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m23s
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 23:04:26 +00:00
giles
e3c8b85812 Add coop fragment middleware and env vars
Some checks failed
Build and Deploy / build-and-deploy (push) Has been cancelled
Fetch nav-tree, auth-menu, cart-mini from coop apps for unified
header. Add INTERNAL_URL env vars for Docker networking. Update
base.html to render fragment blocks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 23:03:43 +00:00
giles
2448dabb83 Restyle base.html to use coop header theme
Some checks failed
Build and Deploy / build-and-deploy (push) Has been cancelled
Match coop light theme: sky header, stone sub-nav pills. Removes
dark-theme nav classes. L2-specific tabs in sub-nav bar.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 23:00:26 +00:00
giles
eed5aff238 Add healthcheck and start-first update for l2-server
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m7s
Zero-downtime deploys: new container starts and passes health
check before the old one is stopped. Caddy always has a healthy
backend to proxy to.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 22:20:00 +00:00
giles
859ff0b835 Eliminate ${VAR} substitutions from docker-compose.yml
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m41s
Move DATABASE_URL and POSTGRES_PASSWORD to .env via env_file.
docker stack deploy no longer needs env vars sourced, and
repeat deploys won't trigger spurious restarts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 22:06:40 +00:00
giles
5e45f24fba Source .env before docker stack deploy in CI
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m27s
docker stack deploy does not read .env files automatically
(unlike docker compose), so ${VAR} substitutions resolve to
empty strings. Source .env to export vars before deploying.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 21:44:38 +00:00
gilesb
fbf188afdc Remove hardcoded secrets from public repo
All checks were successful
Build and Deploy / build-and-deploy (push) Successful in 1m3s
- Remove default password fallback from POSTGRES_PASSWORD in docker-compose.yml
- Remove default password fallback from db.py and migrate.py
- Update .env.example with required POSTGRES_PASSWORD
- Update README to mark DATABASE_URL as required

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 19:29:24 +00:00
giles
8f1ba74c53 Add Gitea Actions CI/CD and use private registry
Some checks failed
Build and Deploy / build-and-deploy (push) Failing after 12s
Add CI workflow mirroring celery pipeline: SSH to deploy server,
git pull, build and push to registry, deploy docker stack.
Update docker-compose to pull l2-server from registry.rose-ash.com:5000.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-06 19:23:22 +00:00
gilesb
655f533439 Add /auth/verify endpoint for L1 token verification
L1 servers call this endpoint to verify tokens during auth callback.
Returns user info if token is valid, 401 if invalid or revoked.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 15:49:39 +00:00
gilesb
8c4a30d18f Simplify renderers to use env-configured L1 servers
- L1 servers now come from L1_SERVERS env var instead of per-user attachment
- Added renderers/list.html template showing available servers
- Health check shows if servers are online
- Elegant error handling for invalid requests (no more raw JSON errors)
- Connect button passes auth token to L1 for seamless login

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 15:36:38 +00:00
giles
dcb487e6f4 Fix renderer list and enable markdown tables
- Fix get_user_renderers usage (returns strings not dicts)
- Enable tables and fenced_code markdown extensions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 13:20:47 +00:00
giles
0a15b2532e Add missing list templates for activities, anchors, storage
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 13:19:07 +00:00
giles
f8f44945ab Fix db function calls and add missing functions
- Fix get_activities to use get_activities_paginated
- Add get_user_assets, delete_asset, count_users, count_user_activities
- Add get_user_activities, get_renderer, update_anchor, delete_anchor
- Add record_run and get_run functions
- Fix create_asset calls to use dict parameter
- Fix update_asset call signature

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 13:13:40 +00:00
giles
65994ac107 Update artdag-common to 889ea98 with prose fix 2026-01-11 13:10:44 +00:00
giles
c3d131644a Fix anchors router to use get_anchors_paginated
Anchors are global, not user-specific. Added paginated db function.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 13:08:37 +00:00
giles
65169f49f9 Pin artdag-common to commit 2163cbd
Forces pip to fetch latest version with typography plugin.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 13:02:24 +00:00
giles
ff7ce1a61e Add cache busting to force pip to re-fetch dependencies
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 12:44:44 +00:00
giles
39870a499c Fix get_activities call to use get_activities_paginated
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 12:29:00 +00:00
giles
bfd38559b3 Update base.html to extend _base.html
Matches renamed template in artdag-common package.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 12:28:28 +00:00
giles
358fbba7b2 Add git to Dockerfile and httpx dependency
- Install git in Docker image for pip to clone git dependencies
- Add httpx package required by auth_service

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 12:11:51 +00:00
giles
0a31e1acfa Add artdag-common dependency 2026-01-11 11:55:41 +00:00
giles
d49e759d5a Refactor to modular app factory architecture
- Replace 3765-line monolithic server.py with 26-line entry point
- All routes now in app/routers/ using Jinja2 templates
- Backup old server as server_legacy.py

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 11:48:24 +00:00
giles
dd3d5927f5 Add /help routes to display README documentation
Provides /help index and /help/{doc_name} routes to view
L1 server and Common library READMEs in the web UI.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 11:29:49 +00:00
giles
c9c4a340fd Remove redundant documentation UI routes
/docs now correctly points to FastAPI's Swagger API docs.
README files can be viewed directly in the git repository.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 11:21:16 +00:00
giles
5730cd0f22 Add documentation routes and update README
- Update README with comprehensive documentation covering ActivityPub,
  OpenTimestamps anchoring, L1 integration, and all API endpoints
- Add /docs routes to serve markdown documentation as styled HTML
- Include common library documentation in web interface

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 09:58:36 +00:00
giles
d1e9287829 Add modular app structure for L2 server
- Create app factory with routers and templates
- Auth, assets, activities, anchors, storage, users, renderers routers
- Federation router for WebFinger and nodeinfo
- Jinja2 templates for L2 pages
- Config and dependency injection

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 07:46:26 +00:00
gilesb
a5619208cf Support activity_id (hash) in /activities/{ref} URL
- Accept both numeric index and activity_id hash
- Look up activity by ID from database when hash provided
- Refactor ui_activity_detail to support both lookup methods

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 18:37:53 +00:00
gilesb
e4cbbb1fbc Create activity for existing assets in record_run
When asset already exists, check if activity exists too.
If no activity, create one for the existing asset.
This fixes the case where an asset was registered but the
activity creation failed or was skipped.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 15:42:06 +00:00
gilesb
678d0e0ea3 Fix NoneType subscript error in record_run
- Add get_asset_by_name_tx for transaction-aware asset lookup
- Use transaction connection instead of separate connection
- Prevents race condition where asset might not be visible

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 15:07:42 +00:00
gilesb
59484936fd Fix db.get_asset_by_name -> db.get_asset
The function is named get_asset(), not get_asset_by_name().

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 12:27:05 +00:00
gilesb
292f7bf316 Add migration to add description column to user_storage table
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 02:48:09 +00:00
gilesb
c1cbf0b4ad Phase 2: Multiple storage configs per type with new UI structure
- Database: Add description field, remove unique constraint to allow
  multiple configs of same provider type
- UI: Main page shows provider types as cards with counts
- UI: Per-type page (/storage/type/{type}) for managing configs
- API: Add get_user_storage_by_type() for filtered queries
- Form: Add description field for distinguishing configs

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 00:53:28 +00:00
gilesb
de7ca82862 Add boto3 for Filebase and Storj S3-compatible storage
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 00:29:05 +00:00
gilesb
2326658518 Fix storage test and delete endpoints to support cookie auth
Both /storage/{id}/test and DELETE /storage/{id} were using Bearer
token auth only. Now they also check cookie auth for browser sessions.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 00:27:05 +00:00
gilesb
770c36479f Add support for more decentralized storage providers
Added 4 new storage providers:
- NFT.Storage (free for NFT data)
- Infura IPFS (5GB free)
- Filebase (5GB free, S3-compatible IPFS)
- Storj (25GB free, decentralized cloud)

Updated UI with 7 total storage options in a 4-column grid,
each with distinct colored borders for visibility.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 00:25:09 +00:00
gilesb
8bef9afb1f Add form-based storage endpoint for browser submissions
The POST /storage endpoint required Bearer token auth and JSON body,
which didn't work with browser form submissions using cookies. Added
new /storage/add endpoint that accepts form data and cookie auth.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 00:19:36 +00:00
gilesb
fb5c46330d Fix storage page authentication to support cookie-based sessions
The /storage route was only checking Bearer token authentication,
causing logged-in browser users to be redirected to login. Now also
checks cookie authentication like other HTML pages.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 00:10:23 +00:00
gilesb
70cde17fef Fix storage provider buttons visibility with colored borders
The storage option buttons were nearly invisible due to low contrast
between bg-dark-600 buttons and bg-dark-700 background. Added distinct
colored borders (blue/green/purple) and darker backgrounds to make
the Pinata, web3.storage, and Local Storage options clearly visible.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 00:04:56 +00:00
gilesb
cf94600d63 Add borders to storage provider buttons for visibility
Buttons had same background color as container, making them nearly
invisible. Added border-dark-500 and hover:border-blue-500.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 23:44:17 +00:00
gilesb
efd3a2dd16 Fix /storage endpoint to default to HTML
Same content negotiation fix as other endpoints - default to HTML
for browsers, only return JSON if explicitly requested.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 23:40:58 +00:00
gilesb
1e3d1bb65e Add user-attachable storage system
Phase 1 of distributed storage implementation:

Database:
- user_storage table for storage providers (Pinata, web3.storage, local)
- storage_pins table to track what's stored where
- source_url/source_type columns on assets for reconstruction

Storage Providers:
- Abstract StorageProvider base class
- PinataProvider for Pinata IPFS pinning
- Web3StorageProvider for web3.storage
- LocalStorageProvider for filesystem storage
- Factory function create_provider()

API Endpoints:
- GET/POST /storage - list/add storage providers
- GET/PATCH/DELETE /storage/{id} - manage individual providers
- POST /storage/{id}/test - test connectivity

UI:
- /storage page with provider cards
- Add provider form (Pinata, web3.storage, local)
- Test/remove buttons per provider
- Usage stats (capacity, donated, used, pins)

50% donation model: half of user capacity is available for
system use to store shared content across the network.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 23:19:10 +00:00
gilesb
64749af3fc Call /auth/revoke-user on L1s during logout
L2 now calls /auth/revoke-user (revokes by username) instead of
/auth/revoke (revokes by token), because L1 has scoped tokens that
differ from L2's own token.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 22:22:22 +00:00
gilesb
5ebfdac887 Add scoped tokens, L2-side revocation, and security docs
Security improvements:
- Tokens now include optional l1_server claim for scoping
- /auth/verify checks token scope matches requesting L1
- L2 maintains revoked_tokens table - even if L1 ignores revoke, token fails
- Logout revokes token in L2 db before notifying L1s
- /renderers/attach creates scoped tokens (not embedded in HTML)
- Add get_token_claims() to auth.py

Database:
- Add revoked_tokens table with token_hash, username, expires_at
- Add db functions: revoke_token, is_token_revoked, cleanup_expired_revocations

Documentation:
- Document security features in README

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 18:21:13 +00:00
gilesb
4351c97ce0 Revoke tokens on attached L1s when user logs out
On logout:
1. Call /auth/revoke on each attached L1 renderer
2. Remove all attachments from user_renderers table
3. Clear L2 cookie

This ensures logging out of L2 also logs user out of all L1s.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 18:08:05 +00:00
gilesb
943ccea1a2 Update Web UI and API routes in README
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 17:56:23 +00:00
gilesb
813f6a1d44 Record renderer attachment when L1 verifies token
When L1 successfully calls /auth/verify, the user's attachment to
that L1 server is recorded in the user_renderers table.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 17:51:15 +00:00
gilesb
5a8ce51c83 Document L1 authorization requirement for token verification
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 17:43:49 +00:00
gilesb
e9df81db40 Require L1 server authorization for token verification
L1 servers must now identify themselves when calling /auth/verify.
Only servers listed in L1_SERVERS can verify tokens.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 17:43:08 +00:00
gilesb
d244a62c48 Document federated auth - no shared secrets required
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 17:40:38 +00:00