From b43d241b0970fce9c5e15d1a68aca421a9906220 Mon Sep 17 00:00:00 2001 From: syui Date: Wed, 12 Mar 2025 21:49:33 +0900 Subject: [PATCH] add patch --- .github/workflows/generate-record.yml | 38 ++ .gitignore | 1 + README.md | 96 +--- at.json | 47 -- compose.yml | 128 ++--- envs/bgs | 4 +- envs/jetstream | 5 + envs/ozone | 8 + envs/pds | 2 + envs/social-app | 4 +- install.zsh | 248 +++++++-- lexicons/ai/syui/card.json | 56 -- lexicons/ai/syui/card/verify.json | 72 --- lexicons/ai/syui/game.json | 27 - lexicons/ai/syui/game/character.json | 80 --- lexicons/ai/syui/game/user.json | 101 ---- lexicons/ai/syui/o/comment.json | 30 -- lexicons/ai/syui/o/post.json | 33 -- lexicons/ai/syui/o/vote.json | 23 - lexicons/com/atproto/repo/applyWrites.json | 126 ----- lexicons/com/atproto/repo/createRecord.json | 72 --- lexicons/com/atproto/repo/defs.json | 14 - lexicons/com/atproto/repo/deleteRecord.json | 56 -- lexicons/com/atproto/repo/describeRepo.json | 51 -- lexicons/com/atproto/repo/getRecord.json | 45 -- lexicons/com/atproto/repo/importRepo.json | 13 - .../com/atproto/repo/listMissingBlobs.json | 44 -- lexicons/com/atproto/repo/listRecords.json | 69 --- lexicons/com/atproto/repo/putRecord.json | 73 --- lexicons/com/atproto/repo/strongRef.json | 15 - lexicons/com/atproto/repo/uploadBlob.json | 23 - patching/120-ozone-runtimeEnvVars.diff | 119 +++++ patching/121-ozone-constants-fix.patch | 99 ++++ patching/122-ozone-enable-daemon.diff | 82 +++ .../130-atproto-ozone-enable-daemon-v2.patch | 28 + .../130-atproto-ozone-enable-daemon.patch | 33 ++ ...ff => 4367-atproto-services-bsky-api.diff} | 93 +++- patching/4367-atproto-services-pds-index.diff | 20 + ...-social-app-disable-external-services.diff | 17 + patching/8980-social-app-disable-proxy.diff | 44 ++ repos_extra/frontpage/diff.patch | 499 ------------------ repos_extra/frontpage/diff_min.patch | 295 ----------- .../frontpage/lexicons/ai/syui/o/comment.json | 30 -- .../frontpage/lexicons/ai/syui/o/post.json | 33 -- .../frontpage/lexicons/ai/syui/o/vote.json | 23 - .../packages-rs/drainpipe/.env.local | 5 - .../frontpage/packages-rs/drainpipe/.keep | 0 .../packages-rs/drainpipe/Dockerfile | 20 - .../packages-rs/drainpipe/docker-compose.yml | 9 - .../packages/atproto-browser/Dockerfile | 10 - .../packages/atproto-browser/compose.yml | 8 - .../frontpage/packages/frontpage/.env.local | 14 - .../frontpage/packages/frontpage/Dockerfile | 17 - .../packages/frontpage/app/(app)/layout.tsx | 4 - .../frontpage/app/(app)/post/game/_action.ts | 26 - .../frontpage/app/(app)/post/game/_client.tsx | 36 -- .../frontpage/app/(app)/post/game/page.tsx | 17 - .../frontpage/packages/frontpage/compose.yml | 8 - .../frontpage/lib/data/atproto/game.ts | 62 --- .../frontpage/lib/data/atproto/record.ts | 50 -- .../frontpage/public/frontpage-logo.svg | 16 - repos_extra/frontpage/readme.md | 245 --------- repos_extra/pdsls/Dockerfile | 11 - repos_extra/pdsls/compose.yml | 6 - repos_extra/pdsls/vite.config.ts | 17 - repos_extra/python-oauth-web-app/Dockerfile | 7 - repos_extra/python-oauth-web-app/app_add.py | 3 - repos_extra/python-oauth-web-app/compose.yml | 10 - .../python-oauth-web-app/templates/about.html | 20 - .../python-oauth-web-app/templates/base.html | 114 ---- .../templates/bsky_post.html | 8 - .../python-oauth-web-app/templates/error.html | 13 - .../templates/favicon.png | Bin 14738 -> 0 bytes .../templates/favicon.svg | 1 - .../python-oauth-web-app/templates/home.html | 29 - .../python-oauth-web-app/templates/login.html | 15 - repos_extra/readme.md | 5 - scpt/at.zsh | 31 +- scpt/src/ai/syui/game/character.zsh | 277 ++++++---- scpt/src/func.zsh | 52 +- scpt/src/is/syu/main.zsh | 18 + scpt/src/tag.zsh | 30 ++ scpt/src/ue.zsh | 193 +++++++ {repos_extra => social-app-custom}/.keep | 0 social-app-custom/AppInfo.tsx | 134 +++++ social-app-custom/LicenseNotice.tsx | 95 ++++ social-app-custom/PrivacyContent.tsx | 163 ++++++ social-app-custom/PrivacyPolicy.screen.tsx | 42 ++ social-app-custom/Support.screen.tsx | 38 ++ social-app-custom/app.config.patch.js | 9 + social-app-custom/bin/build.zsh | 44 ++ social-app-custom/bin/install.zsh | 86 +++ 92 files changed, 1974 insertions(+), 3063 deletions(-) create mode 100644 .github/workflows/generate-record.yml delete mode 100644 at.json create mode 100644 envs/jetstream delete mode 100644 lexicons/ai/syui/card.json delete mode 100644 lexicons/ai/syui/card/verify.json delete mode 100644 lexicons/ai/syui/game.json delete mode 100644 lexicons/ai/syui/game/character.json delete mode 100644 lexicons/ai/syui/game/user.json delete mode 100644 lexicons/ai/syui/o/comment.json delete mode 100644 lexicons/ai/syui/o/post.json delete mode 100644 lexicons/ai/syui/o/vote.json delete mode 100644 lexicons/com/atproto/repo/applyWrites.json delete mode 100644 lexicons/com/atproto/repo/createRecord.json delete mode 100644 lexicons/com/atproto/repo/defs.json delete mode 100644 lexicons/com/atproto/repo/deleteRecord.json delete mode 100644 lexicons/com/atproto/repo/describeRepo.json delete mode 100644 lexicons/com/atproto/repo/getRecord.json delete mode 100644 lexicons/com/atproto/repo/importRepo.json delete mode 100644 lexicons/com/atproto/repo/listMissingBlobs.json delete mode 100644 lexicons/com/atproto/repo/listRecords.json delete mode 100644 lexicons/com/atproto/repo/putRecord.json delete mode 100644 lexicons/com/atproto/repo/strongRef.json delete mode 100644 lexicons/com/atproto/repo/uploadBlob.json create mode 100644 patching/120-ozone-runtimeEnvVars.diff create mode 100644 patching/121-ozone-constants-fix.patch create mode 100644 patching/122-ozone-enable-daemon.diff create mode 100644 patching/130-atproto-ozone-enable-daemon-v2.patch create mode 100644 patching/130-atproto-ozone-enable-daemon.patch rename patching/{105-atproto-services-for-docker.diff => 4367-atproto-services-bsky-api.diff} (52%) create mode 100644 patching/4367-atproto-services-pds-index.diff create mode 100644 patching/8980-social-app-disable-external-services.diff create mode 100644 patching/8980-social-app-disable-proxy.diff delete mode 100644 repos_extra/frontpage/diff.patch delete mode 100644 repos_extra/frontpage/diff_min.patch delete mode 100644 repos_extra/frontpage/lexicons/ai/syui/o/comment.json delete mode 100644 repos_extra/frontpage/lexicons/ai/syui/o/post.json delete mode 100644 repos_extra/frontpage/lexicons/ai/syui/o/vote.json delete mode 100644 repos_extra/frontpage/packages-rs/drainpipe/.env.local delete mode 100644 repos_extra/frontpage/packages-rs/drainpipe/.keep delete mode 100644 repos_extra/frontpage/packages-rs/drainpipe/Dockerfile delete mode 100644 repos_extra/frontpage/packages-rs/drainpipe/docker-compose.yml delete mode 100644 repos_extra/frontpage/packages/atproto-browser/Dockerfile delete mode 100644 repos_extra/frontpage/packages/atproto-browser/compose.yml delete mode 100644 repos_extra/frontpage/packages/frontpage/.env.local delete mode 100644 repos_extra/frontpage/packages/frontpage/Dockerfile delete mode 100644 repos_extra/frontpage/packages/frontpage/app/(app)/layout.tsx delete mode 100644 repos_extra/frontpage/packages/frontpage/app/(app)/post/game/_action.ts delete mode 100644 repos_extra/frontpage/packages/frontpage/app/(app)/post/game/_client.tsx delete mode 100644 repos_extra/frontpage/packages/frontpage/app/(app)/post/game/page.tsx delete mode 100644 repos_extra/frontpage/packages/frontpage/compose.yml delete mode 100644 repos_extra/frontpage/packages/frontpage/lib/data/atproto/game.ts delete mode 100644 repos_extra/frontpage/packages/frontpage/lib/data/atproto/record.ts delete mode 100644 repos_extra/frontpage/packages/frontpage/public/frontpage-logo.svg delete mode 100644 repos_extra/frontpage/readme.md delete mode 100644 repos_extra/pdsls/Dockerfile delete mode 100644 repos_extra/pdsls/compose.yml delete mode 100644 repos_extra/pdsls/vite.config.ts delete mode 100644 repos_extra/python-oauth-web-app/Dockerfile delete mode 100644 repos_extra/python-oauth-web-app/app_add.py delete mode 100644 repos_extra/python-oauth-web-app/compose.yml delete mode 100644 repos_extra/python-oauth-web-app/templates/about.html delete mode 100644 repos_extra/python-oauth-web-app/templates/base.html delete mode 100644 repos_extra/python-oauth-web-app/templates/bsky_post.html delete mode 100644 repos_extra/python-oauth-web-app/templates/error.html delete mode 100644 repos_extra/python-oauth-web-app/templates/favicon.png delete mode 100644 repos_extra/python-oauth-web-app/templates/favicon.svg delete mode 100644 repos_extra/python-oauth-web-app/templates/home.html delete mode 100644 repos_extra/python-oauth-web-app/templates/login.html delete mode 100644 repos_extra/readme.md create mode 100644 scpt/src/is/syu/main.zsh create mode 100755 scpt/src/ue.zsh rename {repos_extra => social-app-custom}/.keep (100%) create mode 100644 social-app-custom/AppInfo.tsx create mode 100644 social-app-custom/LicenseNotice.tsx create mode 100644 social-app-custom/PrivacyContent.tsx create mode 100644 social-app-custom/PrivacyPolicy.screen.tsx create mode 100644 social-app-custom/Support.screen.tsx create mode 100644 social-app-custom/app.config.patch.js create mode 100755 social-app-custom/bin/build.zsh create mode 100644 social-app-custom/bin/install.zsh diff --git a/.github/workflows/generate-record.yml b/.github/workflows/generate-record.yml new file mode 100644 index 0000000..c2a5cc4 --- /dev/null +++ b/.github/workflows/generate-record.yml @@ -0,0 +1,38 @@ +name: Generate Record JSON + +on: + workflow_dispatch: # 手動トリガー + push: + paths: + - scpt/generate_record.py # スクリプトに変更があったとき + schedule: + - cron: '0 3 * * *' # 毎日03:00 UTCに自動生成(任意) + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.x' + + - name: Install Dependencies + run: | + pip install -r requirements.txt || true # 必要なら + + - name: Run Record Generator Script + run: | + python scpt/generate_record.py + + - name: Commit and Push Generated JSON + run: | + git config --global user.name "GitHub Actions Bot" + git config --global user.email "actions@github.com" + git add record.json + git commit -m "🧬 Auto-generate record.json" || echo "No changes to commit" + git push origin main diff --git a/.gitignore b/.gitignore index c05e777..bcb2719 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ repos +.claude diff --git a/README.md b/README.md index 770b8cd..a6bab35 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,12 @@ # at -https://github.com/bluesky-social/atproto +- https://github.com/bluesky-social/atproto +- https://github.com/bluesky-social/atproto/discussions/2026 |word|name|example| |---|---|---| -|at|uri|at://ai.syu.is| -|@|user|@ai.syu.is| +|at|uri|at://example.com| +|@|user|@example.com| |[at]proto|repo|`git@github.com:bluesky-social/atproto`| |[at]mosphere|system|pds, bsky(appview), ozone, bgs, plc| |[a]uthenticated [t]ransfer|protocol|[did](https://www.w3.org/TR/did-core/)| @@ -14,15 +15,13 @@ https://github.com/bluesky-social/atproto ## account -[@ai.syu.is](https://web.syu.is/profile/ai.syu.is) - -- https://at.syu.is/at/yui.syui.ai +- [ai@syu.is](https://syu.is/profile/did:plc:6qyecktefllvenje24fcxnie) +- [ai@bsky.app](https://bsky.app/profile/did:plc:6qyecktefllvenje24fcxnie) - https://plc.syu.is/did:plc:6qyecktefllvenje24fcxnie -- https://plc.directory/did:plc:ytvoptig4ddshmwdsjmhtcym +- https://plc.directory/did:plc:6qyecktefllvenje24fcxnie ```sh $ curl -sL syu.is/xrpc/_health -{"version":"0.4.65"} # latest # https://github.com/bluesky-social/atproto/blob/main/packages/pds/package.json @@ -30,10 +29,11 @@ $ curl -sL https://raw.githubusercontent.com/bluesky-social/atproto/refs/heads/m ``` ```sh -$ curl -sL "syu.is/xrpc/com.atproto.repo.describeRepo?repo=ai.syu.is" |jq -r .did +$ handle=ai.syui.ai +$ curl -sL "syu.is/xrpc/com.atproto.repo.describeRepo?repo=${handle}" |jq -r .did did:plc:6qyecktefllvenje24fcxnie -$ curl -sL "syu.is/xrpc/com.atproto.repo.listRecords?repo=ai.syu.is&collection=app.bsky.feed.post&reverse=true&limit=1" +$ curl -sL "syu.is/xrpc/com.atproto.repo.listRecords?repo=${handle}&collection=app.bsky.feed.post&reverse=true&limit=1" {"records":[{"uri":"at://did:plc:6qyecktefllvenje24fcxnie/app.bsky.feed.post/3l6s2riuouk2j","cid":"bafyreibjohl7va4upkibw5twaxdd4jg3l6rmfatu4dpjjfd5xkb2ijtlx4","value":{"text":"hello","$type":"app.bsky.feed.post","langs":["ja"],"createdAt":"2024-10-18T13:21:39.809Z"}}],"cursor":"3l6s2riuouk2j"} ``` @@ -45,80 +45,4 @@ $ curl -sL "syu.is/xrpc/com.atproto.repo.listRecords?repo=ai.syu.is&collection=a - https://feed.syu.is/xrpc/app.bsky.feed.getFeedSkeleton?feed=at://did:plc:4hqjfn7m6n5hno3doamuhgef/app.bsky.feed.generator/cmd - https://desc.syu.is/xrpc/app.bsky.feed.getFeedSkeleton?feed=at://did:plc:6qyecktefllvenje24fcxnie/app.bsky.feed.generator/cmd -## link -- https://github.com/bluesky-social/atproto -- https://github.com/itaru2622/bluesky-selfhost-env -- https://github.com/bluesky-social/atproto/discussions/2026 - -## self-host - -currently, bsky and bsync require patches to function properly. additionally, social-app is not displaying avatars. for components that are not working, it's recommended to use [itaru2622/bluesky-selfhost-env](https://github.com/itaru2622/bluesky-selfhost-env). this repository provides an environment for self-hosting bluesky. - -- bsky = appview -- ozone = mod - -|name|service|patch| -|---|---|---| -|pds|https://github.com/bluesky-social/atproto/blob/main/services/pds/Dockerfile|| -|bsky|https://github.com/bluesky-social/atproto/blob/main/services/bsky/Dockerfile|[itaru2622/bluesky-atproto-bsky](https://github.com/itaru2622/bluesky-selfhost-env/blob/master/patching/105-atproto-services-for-docker.diff)| -|bsync|https://github.com/bluesky-social/atproto/blob/main/services/bsync/Dockerfile|| -|ozone|https://github.com/bluesky-social/atproto/blob/main/services/ozone/Dockerfile|| -|plc|https://github.com/did-method-plc/did-method-plc/tree/main/packages/server|| -|bgs|https://github.com/bluesky-social/indigo/tree/main/cmd/bigsky|| -|feed|https://github.com/bluesky-social/feed-generator|| -|web|https://github.com/bluesky-social/social-app|[bluesky-selfhost-env](https://github.com/itaru2622/bluesky-selfhost-env/blob/master/patching/160-social-app-disable-hackModifyThumbnailPath.diff)| - -```sh -# BSKY_IMG_URI_ENDPOINT, BSKY_BLOB_CACHE_LOC -# avatar link example -1. https://appview.${host}/img/avatar/plain/${did}/${cid}@jpeg -2. https://${host}/xrpc/com.atproto.sync.getBlob?did=${did}&cid=${cid} -``` - -docker compose will not be published unless you write ports. it is only valid internally. add ports only for what you want to publish. - -## api - -```sh -# create account -url=https://${pds}/xrpc/com.atproto.server.createAccount -json="{\"email\": \"$email\", \"handle\": \"$handle\", \"password\": \"$password\"}" -curl -X POST -H "Content-Type: application/json" -d $json -sL $url -``` - -change `src/pds/handle` to use a name of 3 characters or less. also, you cannot create an account with a name of 3 characters or less from social-app (web client). please create it from api. - -- [/atproto/packages/pds/src/handle/index.ts](https://github.com/bluesky-social/atproto/blame/d4d5a6edba972c0e9976289bde8bc0b42ff547ca/packages/pds/src/handle/index.ts#L86-L88) - -```sh -# invite code -admin_password=xxx -url=https://$host/xrpc/com.atproto.server.createInviteCode -json="{\"useCount\":1}" -curl -X POST -u admin:${admin_password} -H "Content-Type: application/json" -d "$json" -sL $url -``` - -## oauth - -```sh -# https://github.com/bluesky-social/cookbook/tree/main/python-oauth-web-app -$ cd ./repos/cookbook/python-oauth-web-app -$ rye sync -$ rye run python3 -c 'import secrets; print(secrets.token_hex())'|xargs echo FLASK_SECRET_KEY|tr -d ' ' >> .env -$ rye run python3 generate_jwk.py |xargs echo FLASK_CLIENT_SECRET_JWK|tr -d ' ' >> .env -$ cat .env -$ rye run flask run -``` - -please access `127.0.0.1:5000`. it may not work if you use localhost. - -also, oauth doesn't work on localhost. use [ngrok](https://ngrok.com/), [tailscale](https://tailscale.com/), [cloudflare](https://github.com/cloudflare/cloudflared). - -```sh -$ ngrok http http://localhost:5000 -``` - -```sh -$ cloudflared tunnel --url http://localhost:5000 -``` diff --git a/at.json b/at.json deleted file mode 100644 index 7761e07..0000000 --- a/at.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "atmosphere": { - "name": "at", - "repo": "https://github.com/bluesky-social/atproto", - "uri": "https://atproto.com/ja/guides/glossary", - "exosphere": { - "km":[{ "min": 700, "max": 10000 }], - "tag": [ "universe" ] - }, - "thermosphere": { - "km":[{ "min": 80, "max": 700 }], - "tag": [ "aurora" ] - }, - "mesosphere": { - "km":[{ "min": 50, "max": 80 }], - "tag": [ "meteor" ] - }, - "stratosphere": { - "km":[{ "min": 12, "max": 50 }], - "tag": [ "ozone", "bigsky" ], - "service":[ - { "name":"ozone", "repo":"https://github.com/bluesky-social/atproto/tree/main/services/ozone" }, - { "name":"bgs", "repo":"https://github.com/bluesky-social/indigo/tree/main/cmd/bigsky" } - ] - }, - "troposphere": { - "km":[{ "min": 0, "max": 12 }], - "tag": [ "bluesky"], - "service":[ - { "name":"bsky", "repo":"https://github.com/bluesky-social/atproto/tree/main/services/bsky", "tag":[ "api", "appview" ] }, - { "name":"bsync","repo":"https://github.com/bluesky-social/atproto/tree/main/services/bsync" }, - { "name":"pds", "repo":"https://github.com/bluesky-social/atproto/tree/main/services/pds" } - ] - }, - "other": { - "tag": [ "plc", "feed", "oauth", "social-app", "stream" ], - "service":[ - { "name":"plc", "repo":"https://github.com/did-method-plc/did-method-plc/tree/main/packages/server", "tag" : [ "did" ] }, - { "name":"social-app", "repo":"https://github.com/bluesky-social/social-app", "tag": [ "web" ] }, - { "name":"oauth", "repo":"https://github.com/bluesky-social/cookbook/tree/main/python-oauth-web-app" }, - { "name":"feed", "repo":"https://github.com/bluesky-social/feed-generator" }, - { "name":"stream", "repo":"https://github.com/bluesky-social/jetstream" } - ] - } - }, - "ref": "https://en.wikipedia.org/wiki/Atmosphere_of_Earth" -} diff --git a/compose.yml b/compose.yml index 88a53f9..22fda73 100644 --- a/compose.yml +++ b/compose.yml @@ -48,71 +48,11 @@ services: - ./envs/pds volumes: - ./data/pds/:/data/ + command: node --enable-source-maps index.js depends_on: database: condition: service_healthy - bgs: - ports: - - 2470:2470 - build: - context: ./repos/indigo/ - dockerfile: cmd/bigsky/Dockerfile - restart: always - env_file: - - ./envs/bgs - volumes: - - ./data/bgs/:/data/ - depends_on: - database: - condition: service_healthy - -# ozone: -# ports: -# - 2585:3000 -# build: -# context: ./repos/atproto/ -# dockerfile: services/ozone/Dockerfile -# restart: always -# command: node --enable-source-maps api.js -# volumes: -# - ./data/ozone/:/data/ -# - ./repos/ozone.js:/app/services/ozone/api.js:ro -# env_file: -# - ./envs/ozone -# healthcheck: -# test: "wget -q --spider http://localhost:3000/xrpc/_health" -# interval: 5s -# retries: 20 -# depends_on: -# database: -# condition: service_healthy -# -# ozone-daemon: -# build: -# context: ./repos/atproto/ -# dockerfile: services/ozone/Dockerfile -# restart: always -# command: node --enable-source-maps daemon.js -# env_file: -# - ./envs/ozone -# depends_on: -# ozone: -# condition: service_healthy -# database: -# condition: service_healthy - - social-app: - ports: - - 8100:8100 - build: - context: ./repos/social-app/ - dockerfile: Dockerfile - restart: always - env_file: - - ./envs/social-app - command: "/usr/bin/bskyweb serve" - bsky: ports: - 2584:2584 @@ -131,3 +71,69 @@ services: condition: service_healthy redis: condition: service_healthy + + bgs: + ports: + - 2470:2470 + build: + context: ./repos/indigo/ + dockerfile: cmd/bigsky/Dockerfile + restart: always + env_file: + - ./envs/bgs + volumes: + - ./data/bgs/:/data/ + depends_on: + database: + condition: service_healthy + + social-app: + ports: + - 8100:8100 + build: + context: ./repos/social-app/ + dockerfile: Dockerfile + restart: always + env_file: + - ./envs/social-app + command: "/usr/bin/bskyweb serve" + + jetstream: + build: + context: ./repos/jetstream/ + dockerfile: Dockerfile + ports: + - 6008:6008 + volumes: + - ./data/jetstream:/data + restart: always + env_file: + - ./envs/jetstream + + ozone-web: + build: + context: ./repos/ozone/ + ports: + - 2586:3000 + restart: always + volumes: + - ./data/ozone/:/data/ + env_file: + - ./envs/ozone + depends_on: + database: + condition: service_healthy + + ozone: + build: + context: ./repos/atproto/ + dockerfile: services/ozone/Dockerfile + ports: + - 2585:3000 + restart: always + command: node --enable-source-maps api.js + volumes: + - ./data/ozone/:/data/ + env_file: + - ./envs/ozone + diff --git a/envs/bgs b/envs/bgs index fa79239..a5097f3 100644 --- a/envs/bgs +++ b/envs/bgs @@ -2,5 +2,5 @@ DATABASE_URL=postgres://postgres:postgres@database/bgs CARSTORE_DATABASE_URL=postgres://postgres:postgres@database/carstore DATA_DIR=/data ATP_PLC_HOST=https://plc.${host} - -BGS_ADMIN_KEY +BGS_NEW_PDS_PER_DAY_LIMIT=1000 +BGS_ADMIN_KEY= diff --git a/envs/jetstream b/envs/jetstream new file mode 100644 index 0000000..324bbd7 --- /dev/null +++ b/envs/jetstream @@ -0,0 +1,5 @@ +JETSTREAM_WS_URL=wss://bgs.${host}/xrpc/com.atproto.sync.subscribeRepos +JETSTREAM_DATA_DIR=/data +JETSTREAM_LISTEN_ADDR=:6008 +JETSTREAM_METRICS_LISTEN_ADDR=:6009 +JETSTREAM_LIVENESS_TTL=96h diff --git a/envs/ozone b/envs/ozone index 72b0158..72e89eb 100644 --- a/envs/ozone +++ b/envs/ozone @@ -19,3 +19,11 @@ OZONE_DB_MIGRATE=1 OZONE_ADMIN_PASSWORD OZONE_SIGNING_KEY_HEX +OZONE_BLOB_DIVERT_ADMIN_PASSWORD +OZONE_VERIFIER_URL +OZONE_VERIFIER_DID +OZONE_VERIFIER_PASSWORD +OZONE_VERIFIER_ISSUERS_TO_INDEX +OZONE_VERIFIER_JETSTREAM_URL + +OZONE_APPVIEW_PUSH_EVENTS=true diff --git a/envs/pds b/envs/pds index fabc2a4..b2f0241 100644 --- a/envs/pds +++ b/envs/pds @@ -6,6 +6,8 @@ PDS_BLOBSTORE_DISK_LOCATION=/data/img/static PDS_BSKY_APP_VIEW_DID=did:web:bsky.${host} PDS_BSKY_APP_VIEW_URL=https://bsky.${host} PDS_CRAWLERS=https://bgs.${host} +PDS_SEQUENCER_ENABLED=true +PDS_SEQUENCER_DB_LOCATION=/data/sequencer.sqlite PDS_DEV_MODE=true PDS_DID_PLC_URL=https://plc.${host} PDS_ENABLE_DID_DOC_WITH_SESSION=true diff --git a/envs/social-app b/envs/social-app index a6752de..a1bc28f 100644 --- a/envs/social-app +++ b/envs/social-app @@ -1 +1,3 @@ -ATP_APPVIEW_HOST=https://bsky.${host} +ATP_APPVIEW_HOST=https://public.api.bsky.app +EXPO_PUBLIC_BLUESKY_PROXY_DID=did:web:api.bsky.app +EXPO_PUBLIC_ENV=production diff --git a/install.zsh b/install.zsh index 21f11c6..758b81d 100755 --- a/install.zsh +++ b/install.zsh @@ -1,7 +1,7 @@ #!/bin/zsh # ./install.zsh $HOST - +repos_v='{}' function at-repos-env() { host=$1 if [ -z "$1" ];then @@ -15,11 +15,15 @@ function at-repos-env() { https://github.com/bluesky-social/atproto https://github.com/bluesky-social/social-app https://github.com/bluesky-social/feed-generator + https://github.com/bluesky-social/ozone + https://github.com/bluesky-social/jetstream ) + services=( bsky plc pds jetstream bgs ozone social-app ) d=${0:a:h} dh=${0:a:h:h} name=${host%%.*} domain=${host##*.} + dport=5000 } function at-repos-json() { @@ -55,6 +59,7 @@ function at-repos-clone() { echo $repo if [ ! -d $d/repos/${repo##*/} ];then git clone $repo + fi done if [ ! -f $d/repos/feed-generator/Dockerfile ] && [ -f $d/docker/feed/Dockerfile ];then @@ -69,11 +74,18 @@ function at-repos-pull() { echo $repo if [ -d $d/repos/${repo##*/} ];then cd $d/repos/${repo##*/} + git stash if ! git pull;then rm -rf $d/repos/${repo##*/} at-repos-clone fi fi + rv=$(echo "$repos_v" | jq -r ".[\"${repo##*/}\"]") + if [ "$rv" != "null" ];then + cd $d/repos/${repo##*/} + git reset --hard $rv + cd .. + fi done cd $d } @@ -90,64 +102,234 @@ function at-repos-social-app-icon-origin() { curl -sL $icon -o $d/icons/Logotype.tsx } -function at-repos-social-app-write() { - did_admin=did:plc:z72i7hdynmk6r22z27h6tvur - +function at-repos-social-app-avatar-write() { + did_admin=did:plc:6qyecktefllvenje24fcxnie dt=$d/repos/social-app/src cd $dt - grep -R bsky.social .|cut -d : -f 1|sort -u|xargs sed -i "s/bsky.social/${host}/g" - grep -R bsky.app .|cut -d : -f 1|sort -u|xargs sed -i "s/bsky.app/web.${host}/g" + grep -R syu.is .|cut -d : -f 1|sort -u|xargs sed -i "s/syu.is/${host}/g" + grep -R web.syu.is .|cut -d : -f 1|sort -u|xargs sed -i "s/web.syu.is/web.${host}/g" f=$dt/lib/constants.ts - sed -i "s/public.api.web/bsky/g" $f + sed -i "s#export const BSKY_SERVICE = 'https://bsky.social'#export const BSKY_SERVICE = 'https://${host}'#g" $f + sed -i "s#export const BSKY_SERVICE_DID = 'did:web:bsky.social'#export const BSKY_SERVICE_DID = 'did:web:${host}'#g" $f + sed -i "s#export const PUBLIC_BSKY_SERVICE = 'https://public.api.bsky.app'#export const PUBLIC_BSKY_SERVICE = 'https://bsky.${host}'#g" $f + sed -i "s#export const PUBLIC_APPVIEW = 'https://api.bsky.app'#export const PUBLIC_APPVIEW = 'https://bsky.${host}'#g" $f + sed -i "s#export const PUBLIC_APPVIEW_DID = 'did:web:api.bsky.app'#export const PUBLIC_APPVIEW_DID = 'did:web:bsky.${host}'#g" $f + + # Disable external services (CORS fix) + f=$dt/state/geolocation/const.ts + curl -sL https://raw.githubusercontent.com/bluesky-social/social-app/refs/heads/main/src/state/geolocation/const.ts -o $f + cat > $f << 'GEOEOF' +import {type GeolocationStatus} from '#/state/geolocation/types' +import {BAPP_CONFIG_DEV_URL, IS_DEV} from '#/env' +import {type Device} from '#/storage' + +export const IPCC_URL = `https://bsky.app/ipcc` +// Disabled for self-hosted environment to avoid CORS errors +export const BAPP_CONFIG_URL_PROD = null +export const BAPP_CONFIG_URL = null +export const GEOLOCATION_CONFIG_URL = BAPP_CONFIG_URL + +export const DEFAULT_GEOLOCATION_CONFIG: Device['geolocation'] = { + countryCode: undefined, + regionCode: undefined, + ageRestrictedGeos: [], + ageBlockedGeos: [], +} + +export const DEFAULT_GEOLOCATION_STATUS: GeolocationStatus = { + countryCode: undefined, + regionCode: undefined, + isAgeRestrictedGeo: false, + isAgeBlockedGeo: false, +} +GEOEOF + + # Add null check to geolocation config.ts to prevent fetch(null) errors + f=$dt/state/geolocation/config.ts + curl -sL https://raw.githubusercontent.com/bluesky-social/social-app/refs/heads/main/src/state/geolocation/config.ts -o $f + # Add null check at the beginning of getGeolocationConfig function (after line with 'url: string,') + sed -i "s/): Promise {/): Promise {\n if (!url) return undefined/" $f + + # Disable Statsig (CORS fix) + f=$dt/lib/statsig/statsig.tsx + sed -i "s#api: 'https://events.bsky.app/v2'#api: '' // Disabled for self-hosted#g" $f + # Disable SDK initialization to prevent statsigapi.net connections + sed -i "s#const SDK_KEY = 'client-SXJakO39w9vIhl3D44u8UupyzFl4oZ2qPIkjwcvuPsV'#const SDK_KEY = '' // Disabled for self-hosted#g" $f + f=$dt/view/icons/Logotype.tsx o=$d/icons/Logotype.tsx cp -rf $o $f f=$dt/view/com/util/UserAvatar.tsx curl -sL https://raw.githubusercontent.com/bluesky-social/social-app/refs/heads/main/src/view/com/util/UserAvatar.tsx -o $f - sed -i "s#/img/avatar/plain/#https://cdn.bsky.app/img/avatar/plain/#g" $f + sed -i "s#/img/avatar/plain/#https://cdn.web.syu.is/img/avatar/plain/#g" $f sed -i "s#/img/avatar_thumbnail/plain/#https://bsky.${host}/img/avatar/plain/#g" $f sed -i "s#source={{uri: avatar}}#source={{ uri: hackModifyThumbnailPath(avatar, 1 > 0), }}#g" $f - sed -i "s#https://go.web.${host}/redirect?u=##g" $dt/lib/strings/url-helpers.ts + curl -sL https://raw.githubusercontent.com/bluesky-social/social-app/refs/heads/main/src/lib/strings/url-helpers.ts -o $dt/lib/strings/url-helpers.ts + sed -i "s#https://go.web.syu.is/redirect?u=\${encodeURIComponent(url)}#\${url}#g" $dt/lib/strings/url-helpers.ts grep -R $did_admin .|cut -d : -f 1|sort -u|xargs sed -i "s/${did_admin}/${did}/g" } -function at-repos-bsky-patch() { +function at-repos-atproto-service-bsky-api-patch() { + # https://github.com/itaru2622/bluesky-selfhost-env/blob/master/patching/105-atproto-services-for-docker.diff f=$d/repos/atproto/services/bsky/api.js curl -sL https://raw.githubusercontent.com/bluesky-social/atproto/refs/heads/main/services/bsky/api.js -o $f d_=$d/repos/atproto - p_=$d/patching/105-atproto-services-for-docker.diff - cd ${d_} - if [ ! -f ${p_} ];then - # https://github.com/itaru2622/bluesky-selfhost-env/blob/master/patching/105-atproto-services-for-docker.diff - echo download patch: https://github.com/itaru2622/bluesky-selfhost-env/blob/master/patching/105-atproto-services-for-docker.diff - curl -sLO https://raw.githubusercontent.com/itaru2622/bluesky-selfhost-env/refs/heads/master/patching/105-atproto-services-for-docker.diff - else - echo local patch - fi + p_=$d/patching/4367-atproto-services-bsky-api.diff echo "applying patch: under ${f} for ${p_}" pushd ${d_} patch -p1 < ${p_} popd } -function at-repos-docker() { +function at-repos-atproto-service-pds-index-patch() { + f=$d/repos/atproto/services/pds/index.js + curl -sL https://raw.githubusercontent.com/bluesky-social/atproto/refs/heads/main/services/pds/index.js -o $f + d_=$d/repos/atproto + p_=$d/patching/4367-atproto-services-pds-index.diff + echo "applying patch: under ${f} for ${p_}" + pushd ${d_} + patch -p1 < ${p_} + popd +} + +function at-repos-social-app-agent-patch() { + f=$d/repos/social-app/src/state/session/agent.ts + p_=$d/patching/8980-social-app-disable-proxy.diff + d_=$d/repos/social-app + echo "applying patch: under ${f} for ${p_}" + pushd ${d_} + patch -p1 < ${p_} + popd +} + +function at-repos-social-app-disable-external-services-patch() { + f=$d/repos/social-app/src/state/geolocation/const.ts + p_=$d/patching/8980-social-app-disable-external-services.diff + d_=$d/repos/social-app + echo "applying patch: under ${f} for ${p_}" + pushd ${d_} + patch -p1 < ${p_} + popd +} + +function at-repos-atproto-service-ozone-api-patch() { + f=$d/repos/atproto/services/ozone/api.js + d_=$d/repos/atproto + p_=$d/patching/130-atproto-ozone-enable-daemon-v2.patch + echo "applying patch: under ${f} for ${p_}" + pushd ${d_} + patch -p1 < ${p_} + popd +} + +function at-repos-ozone-patch() { + #DOMAIN=syu.is + cd $d/repos + d_=$d/repos/ozone + rm -rf ${d_} + p_=$d/patching/120-ozone-runtimeEnvVars.diff + git clone https://github.com/bluesky-social/ozone + cd ${d_} + pushd ${d_} + echo "applying patch: under ${d_} for ${p_}" + patch -p1 < ${p_} + popd + + p_=$d/patching/122-ozone-enable-daemon.diff + echo "applying patch: under ${d_} for ${p_}" + pushd ${d_} + patch -p1 < ${p_} + popd + + p_=$d/patching/121-ozone-constants-fix.patch + echo "applying patch: under ${d_} for ${p_}" + pushd ${d_} + patch -p1 < ${p_} || true + popd + #cp -rf $d/repos/atproto/service/ozone/* $d/ozone/service/ +} + +function at-repos-build-docker-atproto() { cd $d - sudo docker compose build && sudo docker compose up -d + docker image prune -a + if [ -z "$1" ];then + for ((i=1; i<=${#services}; i++)); do + service=${services[$i]} + docker compose build --no-cache $service + done + else + docker compose build --no-cache $1 + fi +} + +function at-repos-push-reset() { + docker restart registry + docker stop registry + docker rm registry + docker volume rm registry-data 2>/dev/null || true + docker run -d -p ${dport}:${dport} --name registry \ + --restart=always \ + -v registry-data:/var/lib/registry \ + registry:2 + sleep 3 + docker run -d -p ${dport}:${dport} --name registry --restart=always registry:2 +} + +function at-repos-push-docker() { + if [ -z "$1" ];then + for ((i=1; i<=${#services}; i++)); do + service=${services[$i]} + docker tag at-${service}:latest localhost:${dport}/${service}:latest + docker push localhost:${dport}/${service}:latest + if [ "$service" = "ozone" ];then + docker tag at-${service}:latest localhost:${dport}/${service}-web:latest + docker push localhost:${dport}/${service}-web:latest + fi + done + else + docker tag at-${1}:latest localhost:${dport}/${1}:latest + docker push localhost:${dport}/${1}:latest + fi +} + +function at-repos-pull-docker() { + cd $d + docker image prune -a + docker compose up -d --pull always +} + +function at-origin-social-app() { + cp -rf $d/social-app-custom $d/repos/social-app } at-repos-env -at-repos-clone -at-repos-pull -at-repos-social-app-icon -at-repos-social-app-icon-origin -at-repos-social-app-write -at-repos-bsky-patch - -echo "[y]docker compose build && up" -read key -case $key in - [yY]) - at-repos-docker +case "`cat /etc/hostname`" in + at) + at-repos-pull-docker + exit + ;; + *) + at-repos-push-reset + at-repos-clone + at-repos-pull + at-repos-social-app-icon + at-repos-social-app-icon-origin + at-repos-social-app-avatar-write + at-repos-social-app-agent-patch + at-repos-social-app-disable-external-services-patch + at-repos-atproto-service-bsky-api-patch + at-repos-atproto-service-pds-index-patch + at-repos-atproto-service-ozone-api-patch + at-repos-ozone-patch + if [ -n "$1" ];then + at-repos-build-docker-atproto $1 + at-repos-push-docker $1 + exit + fi + at-repos-build-docker-atproto + at-repos-push-docker + cd $d; docker compose down ;; esac + diff --git a/lexicons/ai/syui/card.json b/lexicons/ai/syui/card.json deleted file mode 100644 index b809cca..0000000 --- a/lexicons/ai/syui/card.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "lexicon": 1, - "id": "ai.syui.card", - "defs": { - "main": { - "type": "record", - "description": "Record containing a cards box.", - "key": "tid", - "record": { - "type": "object", - "required": ["verify", "createdAt"], - "properties": { - "id":{ - "type": "integer", - "minimum": 0, - "maximum": 14, - "default": 0 - }, - "cp":{ - "type": "integer", - "minimum": 1, - "maximum": 5000, - "default": 1 - }, - "rank":{ - "type": "integer", - "minimum": 0, - "maximum": 7, - "default": 0 - }, - "rare": { - "type": "string", - "enum": ["normal", "super", "ultra", "yui", "ai"], - "default": "normal" - }, - "author": { - "type": "string", - "format": "uri", - "description": "https://verify...", - "default": "https://yui.syui.ai" - }, - "verify": { - "type": "string", - "format": "at-uri", - "description": "at://verify..." - }, - "createdAt": { - "type": "string", - "format": "datetime", - "description": "Client-declared timestamp when this post was originally created." - } - } - } - } - } -} diff --git a/lexicons/ai/syui/card/verify.json b/lexicons/ai/syui/card/verify.json deleted file mode 100644 index 8d256e7..0000000 --- a/lexicons/ai/syui/card/verify.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "lexicon": 1, - "id": "ai.syui.card.verify", - "defs": { - "main": { - "type": "record", - "description": "Record containing a card verify.", - "key": "tid", - "record": { - "type": "object", - "required": [ - "handle", - "did", - "createdAt" - ], - "properties": { - "id": { - "type": "integer", - "minimum": 0, - "maximum": 14, - "default": 0 - }, - "cp": { - "type": "integer", - "minimum": 1, - "maximum": 10000, - "default": 1 - }, - "rank": { - "type": "integer", - "minimum": 0, - "maximum": 7, - "default": 0 - }, - "rare": { - "type": "string", - "enum": [ - "normal", - "super", - "ultra", - "yui", - "ai" - ], - "default": "normal" - }, - "handle": { - "type": "string", - "maxLength": 32, - "maxGraphemes": 32 - }, - "did": { - "type": "string" - }, - "embed": { - "type": "union", - "refs": [ - "app.bsky.embed.images", - "app.bsky.embed.external", - "app.bsky.embed.record", - "app.bsky.embed.recordWithMedia" - ] - }, - "createdAt": { - "type": "string", - "format": "datetime", - "description": "Client-declared timestamp when this post was originally created." - } - } - } - } - } -} diff --git a/lexicons/ai/syui/game.json b/lexicons/ai/syui/game.json deleted file mode 100644 index cfdeb13..0000000 --- a/lexicons/ai/syui/game.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "lexicon": 1, - "id": "ai.syui.game", - "defs": { - "main": { - "type": "record", - "description": "Record containing a game.", - "key": "literal:self", - "record": { - "type": "object", - "required": ["account", "createdAt"], - "properties": { - "account": { - "type": "string", - "format": "at-uri", - "description": "at://verify..." - }, - "createdAt": { - "type": "string", - "format": "datetime", - "description": "Client-declared timestamp when this post was originally created." - } - } - } - } - } -} diff --git a/lexicons/ai/syui/game/character.json b/lexicons/ai/syui/game/character.json deleted file mode 100644 index 8949966..0000000 --- a/lexicons/ai/syui/game/character.json +++ /dev/null @@ -1,80 +0,0 @@ -{ - "lexicon": 1, - "id": "ai.syui.game.character", - "defs": { - "main": { - "type": "record", - "key": "string", - "description": "record containing a game character.", - "input": { - "encoding": "application/json", - "record": { - "type": "object", - "required": [ - "createdAt" - ], - "charactor": { - "type": "object", - "enum": [ - "ai", - "manny", - "quinn", - "chinese", - "phoenix", - "kirin", - "leviathan", - "wyvern", - "cerberus", - "dragon", - "kitsune", - "pegasus" - ], - "properties": { - "type": "object", - "properties": { - "season": { - "type": "integer", - "minimum": 0, - "maximum": 3, - "default": 1 - }, - "group": { - "type": "string", - "default": "fantasy", - "enum": [ - "origin", - "fantasy", - "animal" - ] - }, - "gender": { - "type": "string", - "enum": [ - "none", - "male", - "famale" - ] - }, - "fullname": { - "type": "string" - }, - "nickname": { - "type": "string" - } - } - } - }, - "createdAt": { - "type": "string", - "format": "datetime", - "description": "Client-declared timestamp when this post was originally created." - }, - "updatedAt": { - "type": "string", - "format": "datetime" - } - } - } - } - } -} diff --git a/lexicons/ai/syui/game/user.json b/lexicons/ai/syui/game/user.json deleted file mode 100644 index 9d3724f..0000000 --- a/lexicons/ai/syui/game/user.json +++ /dev/null @@ -1,101 +0,0 @@ -{ - "lexicon": 1, - "id": "ai.syui.game.user", - "defs": { - "main": { - "type": "record", - "key": "tid", - "description": "Record containing a game user.", - "input": { - "encoding": "application/json", - "record": { - "type": "object", - "required": ["did", "createdAt"], - "properties": { - "aiten":{ - "type": "integer", - "default": 0 - }, - "did": { - "type": "string" - }, - "login": { - "type": "bool" - }, - "limit": { - "type": "bool" - }, - "charactor": { - "type": "object", - "enum": ["ai","cerberus","chinesedragon","dragon","kirin","kitsune","leviathan","pegasus","phoenix"], - "properties": { - "type": "object", - "properties": { - "group":{ - "type": "string" - }, - "season":{ - "type": "integer" - }, - "lv":{ - "type": "integer", - "minimum": 1, - "maximum": 7, - "default": 1 - }, - "exp":{ - "type": "integer" - }, - "rank":{ - "type": "integer", - "minimum": 0, - "maximum": 7, - "default": 0 - }, - "mode":{ - "type": "integer", - "minimum": 0, - "maximum": 7, - "default": 0 - }, - "hp":{ - "type": "integer", - "maximum": 255, - "default": 0 - }, - "attach":{ - "type": "integer", - "minimum": 1, - "maximum": 255, - "default": 1 - }, - "critical":{ - "type": "integer", - "minimum": 0, - "maximum": 255, - "default": 0 - }, - "critical_d":{ - "type": "integer", - "minimum": 0, - "maximum": 255, - "default": 0 - } - } - } - }, - "createdAt": { - "type": "string", - "format": "datetime", - "description": "Client-declared timestamp when this post was originally created." - }, - "updatedAt": { - "type": "string", - "format": "datetime" - } - } - } - } - } - } -} diff --git a/lexicons/ai/syui/o/comment.json b/lexicons/ai/syui/o/comment.json deleted file mode 100644 index c52ec9d..0000000 --- a/lexicons/ai/syui/o/comment.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "lexicon": 1, - "id": "ai.syui.o.comment", - "defs": { - "main": { - "type": "record", - "description": "Record containing a Frontpage comment.", - "key": "tid", - "record": { - "type": "object", - "required": ["content", "createdAt", "post"], - "properties": { - "content": { - "type": "string", - "maxLength": 100000, - "maxGraphemes": 10000, - "description": "The content of the comment." - }, - "createdAt": { - "type": "string", - "format": "datetime", - "description": "Client-declared timestamp when this comment was originally created." - }, - "parent": { "type": "ref", "ref": "com.atproto.repo.strongRef" }, - "post": { "type": "ref", "ref": "com.atproto.repo.strongRef" } - } - } - } - } -} diff --git a/lexicons/ai/syui/o/post.json b/lexicons/ai/syui/o/post.json deleted file mode 100644 index b18659c..0000000 --- a/lexicons/ai/syui/o/post.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "lexicon": 1, - "id": "ai.syui.o.post", - "defs": { - "main": { - "type": "record", - "description": "Record containing a Frontpage post.", - "key": "tid", - "record": { - "type": "object", - "required": ["title", "url", "createdAt"], - "properties": { - "title": { - "type": "string", - "maxLength": 3000, - "maxGraphemes": 300, - "description": "The title of the post." - }, - "url": { - "type": "string", - "format": "uri", - "description": "The URL of the post." - }, - "createdAt": { - "type": "string", - "format": "datetime", - "description": "Client-declared timestamp when this post was originally created." - } - } - } - } - } -} diff --git a/lexicons/ai/syui/o/vote.json b/lexicons/ai/syui/o/vote.json deleted file mode 100644 index 0870658..0000000 --- a/lexicons/ai/syui/o/vote.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "lexicon": 1, - "id": "ai.syui.o.vote", - "defs": { - "main": { - "type": "record", - "description": "Record containing a Frontpage vote.", - "key": "tid", - "record": { - "type": "object", - "required": ["subject", "createdAt"], - "properties": { - "subject": { "type": "ref", "ref": "com.atproto.repo.strongRef" }, - "createdAt": { - "type": "string", - "format": "datetime", - "description": "Client-declared timestamp when this vote was originally created." - } - } - } - } - } -} diff --git a/lexicons/com/atproto/repo/applyWrites.json b/lexicons/com/atproto/repo/applyWrites.json deleted file mode 100644 index 26dd96c..0000000 --- a/lexicons/com/atproto/repo/applyWrites.json +++ /dev/null @@ -1,126 +0,0 @@ -{ - "lexicon": 1, - "id": "com.atproto.repo.applyWrites", - "defs": { - "main": { - "type": "procedure", - "description": "Apply a batch transaction of repository creates, updates, and deletes. Requires auth, implemented by PDS.", - "input": { - "encoding": "application/json", - "schema": { - "type": "object", - "required": ["repo", "writes"], - "properties": { - "repo": { - "type": "string", - "format": "at-identifier", - "description": "The handle or DID of the repo (aka, current account)." - }, - "validate": { - "type": "boolean", - "description": "Can be set to 'false' to skip Lexicon schema validation of record data across all operations, 'true' to require it, or leave unset to validate only for known Lexicons." - }, - "writes": { - "type": "array", - "items": { - "type": "union", - "refs": ["#create", "#update", "#delete"], - "closed": true - } - }, - "swapCommit": { - "type": "string", - "description": "If provided, the entire operation will fail if the current repo commit CID does not match this value. Used to prevent conflicting repo mutations.", - "format": "cid" - } - } - } - }, - "output": { - "encoding": "application/json", - "schema": { - "type": "object", - "required": [], - "properties": { - "commit": { - "type": "ref", - "ref": "com.atproto.repo.defs#commitMeta" - }, - "results": { - "type": "array", - "items": { - "type": "union", - "refs": ["#createResult", "#updateResult", "#deleteResult"], - "closed": true - } - } - } - } - }, - "errors": [ - { - "name": "InvalidSwap", - "description": "Indicates that the 'swapCommit' parameter did not match current commit." - } - ] - }, - "create": { - "type": "object", - "description": "Operation which creates a new record.", - "required": ["collection", "value"], - "properties": { - "collection": { "type": "string", "format": "nsid" }, - "rkey": { "type": "string", "maxLength": 15 }, - "value": { "type": "unknown" } - } - }, - "update": { - "type": "object", - "description": "Operation which updates an existing record.", - "required": ["collection", "rkey", "value"], - "properties": { - "collection": { "type": "string", "format": "nsid" }, - "rkey": { "type": "string" }, - "value": { "type": "unknown" } - } - }, - "delete": { - "type": "object", - "description": "Operation which deletes an existing record.", - "required": ["collection", "rkey"], - "properties": { - "collection": { "type": "string", "format": "nsid" }, - "rkey": { "type": "string" } - } - }, - "createResult": { - "type": "object", - "required": ["uri", "cid"], - "properties": { - "uri": { "type": "string", "format": "at-uri" }, - "cid": { "type": "string", "format": "cid" }, - "validationStatus": { - "type": "string", - "knownValues": ["valid", "unknown"] - } - } - }, - "updateResult": { - "type": "object", - "required": ["uri", "cid"], - "properties": { - "uri": { "type": "string", "format": "at-uri" }, - "cid": { "type": "string", "format": "cid" }, - "validationStatus": { - "type": "string", - "knownValues": ["valid", "unknown"] - } - } - }, - "deleteResult": { - "type": "object", - "required": [], - "properties": {} - } - } -} diff --git a/lexicons/com/atproto/repo/createRecord.json b/lexicons/com/atproto/repo/createRecord.json deleted file mode 100644 index 7290085..0000000 --- a/lexicons/com/atproto/repo/createRecord.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "lexicon": 1, - "id": "com.atproto.repo.createRecord", - "defs": { - "main": { - "type": "procedure", - "description": "Create a single new repository record. Requires auth, implemented by PDS.", - "input": { - "encoding": "application/json", - "schema": { - "type": "object", - "required": ["repo", "collection", "record"], - "properties": { - "repo": { - "type": "string", - "format": "at-identifier", - "description": "The handle or DID of the repo (aka, current account)." - }, - "collection": { - "type": "string", - "format": "nsid", - "description": "The NSID of the record collection." - }, - "rkey": { - "type": "string", - "description": "The Record Key.", - "maxLength": 15 - }, - "validate": { - "type": "boolean", - "description": "Can be set to 'false' to skip Lexicon schema validation of record data, 'true' to require it, or leave unset to validate only for known Lexicons." - }, - "record": { - "type": "unknown", - "description": "The record itself. Must contain a $type field." - }, - "swapCommit": { - "type": "string", - "format": "cid", - "description": "Compare and swap with the previous commit by CID." - } - } - } - }, - "output": { - "encoding": "application/json", - "schema": { - "type": "object", - "required": ["uri", "cid"], - "properties": { - "uri": { "type": "string", "format": "at-uri" }, - "cid": { "type": "string", "format": "cid" }, - "commit": { - "type": "ref", - "ref": "com.atproto.repo.defs#commitMeta" - }, - "validationStatus": { - "type": "string", - "knownValues": ["valid", "unknown"] - } - } - } - }, - "errors": [ - { - "name": "InvalidSwap", - "description": "Indicates that 'swapCommit' didn't match current repo commit." - } - ] - } - } -} diff --git a/lexicons/com/atproto/repo/defs.json b/lexicons/com/atproto/repo/defs.json deleted file mode 100644 index 0f5128f..0000000 --- a/lexicons/com/atproto/repo/defs.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "lexicon": 1, - "id": "com.atproto.repo.defs", - "defs": { - "commitMeta": { - "type": "object", - "required": ["cid", "rev"], - "properties": { - "cid": { "type": "string", "format": "cid" }, - "rev": { "type": "string" } - } - } - } -} diff --git a/lexicons/com/atproto/repo/deleteRecord.json b/lexicons/com/atproto/repo/deleteRecord.json deleted file mode 100644 index fb9b90b..0000000 --- a/lexicons/com/atproto/repo/deleteRecord.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "lexicon": 1, - "id": "com.atproto.repo.deleteRecord", - "defs": { - "main": { - "type": "procedure", - "description": "Delete a repository record, or ensure it doesn't exist. Requires auth, implemented by PDS.", - "input": { - "encoding": "application/json", - "schema": { - "type": "object", - "required": ["repo", "collection", "rkey"], - "properties": { - "repo": { - "type": "string", - "format": "at-identifier", - "description": "The handle or DID of the repo (aka, current account)." - }, - "collection": { - "type": "string", - "format": "nsid", - "description": "The NSID of the record collection." - }, - "rkey": { - "type": "string", - "description": "The Record Key." - }, - "swapRecord": { - "type": "string", - "format": "cid", - "description": "Compare and swap with the previous record by CID." - }, - "swapCommit": { - "type": "string", - "format": "cid", - "description": "Compare and swap with the previous commit by CID." - } - } - } - }, - "output": { - "encoding": "application/json", - "schema": { - "type": "object", - "properties": { - "commit": { - "type": "ref", - "ref": "com.atproto.repo.defs#commitMeta" - } - } - } - }, - "errors": [{ "name": "InvalidSwap" }] - } - } -} diff --git a/lexicons/com/atproto/repo/describeRepo.json b/lexicons/com/atproto/repo/describeRepo.json deleted file mode 100644 index b1ce2b6..0000000 --- a/lexicons/com/atproto/repo/describeRepo.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "lexicon": 1, - "id": "com.atproto.repo.describeRepo", - "defs": { - "main": { - "type": "query", - "description": "Get information about an account and repository, including the list of collections. Does not require auth.", - "parameters": { - "type": "params", - "required": ["repo"], - "properties": { - "repo": { - "type": "string", - "format": "at-identifier", - "description": "The handle or DID of the repo." - } - } - }, - "output": { - "encoding": "application/json", - "schema": { - "type": "object", - "required": [ - "handle", - "did", - "didDoc", - "collections", - "handleIsCorrect" - ], - "properties": { - "handle": { "type": "string", "format": "handle" }, - "did": { "type": "string", "format": "did" }, - "didDoc": { - "type": "unknown", - "description": "The complete DID document for this account." - }, - "collections": { - "type": "array", - "description": "List of all the collections (NSIDs) for which this repo contains at least one record.", - "items": { "type": "string", "format": "nsid" } - }, - "handleIsCorrect": { - "type": "boolean", - "description": "Indicates if handle is currently valid (resolves bi-directionally)" - } - } - } - } - } - } -} diff --git a/lexicons/com/atproto/repo/getRecord.json b/lexicons/com/atproto/repo/getRecord.json deleted file mode 100644 index 261c1cd..0000000 --- a/lexicons/com/atproto/repo/getRecord.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "lexicon": 1, - "id": "com.atproto.repo.getRecord", - "defs": { - "main": { - "type": "query", - "description": "Get a single record from a repository. Does not require auth.", - "parameters": { - "type": "params", - "required": ["repo", "collection", "rkey"], - "properties": { - "repo": { - "type": "string", - "format": "at-identifier", - "description": "The handle or DID of the repo." - }, - "collection": { - "type": "string", - "format": "nsid", - "description": "The NSID of the record collection." - }, - "rkey": { "type": "string", "description": "The Record Key." }, - "cid": { - "type": "string", - "format": "cid", - "description": "The CID of the version of the record. If not specified, then return the most recent version." - } - } - }, - "output": { - "encoding": "application/json", - "schema": { - "type": "object", - "required": ["uri", "value"], - "properties": { - "uri": { "type": "string", "format": "at-uri" }, - "cid": { "type": "string", "format": "cid" }, - "value": { "type": "unknown" } - } - } - }, - "errors": [{ "name": "RecordNotFound" }] - } - } -} diff --git a/lexicons/com/atproto/repo/importRepo.json b/lexicons/com/atproto/repo/importRepo.json deleted file mode 100644 index fc850b1..0000000 --- a/lexicons/com/atproto/repo/importRepo.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "lexicon": 1, - "id": "com.atproto.repo.importRepo", - "defs": { - "main": { - "type": "procedure", - "description": "Import a repo in the form of a CAR file. Requires Content-Length HTTP header to be set.", - "input": { - "encoding": "application/vnd.ipld.car" - } - } - } -} diff --git a/lexicons/com/atproto/repo/listMissingBlobs.json b/lexicons/com/atproto/repo/listMissingBlobs.json deleted file mode 100644 index c39913d..0000000 --- a/lexicons/com/atproto/repo/listMissingBlobs.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "lexicon": 1, - "id": "com.atproto.repo.listMissingBlobs", - "defs": { - "main": { - "type": "query", - "description": "Returns a list of missing blobs for the requesting account. Intended to be used in the account migration flow.", - "parameters": { - "type": "params", - "properties": { - "limit": { - "type": "integer", - "minimum": 1, - "maximum": 1000, - "default": 500 - }, - "cursor": { "type": "string" } - } - }, - "output": { - "encoding": "application/json", - "schema": { - "type": "object", - "required": ["blobs"], - "properties": { - "cursor": { "type": "string" }, - "blobs": { - "type": "array", - "items": { "type": "ref", "ref": "#recordBlob" } - } - } - } - } - }, - "recordBlob": { - "type": "object", - "required": ["cid", "recordUri"], - "properties": { - "cid": { "type": "string", "format": "cid" }, - "recordUri": { "type": "string", "format": "at-uri" } - } - } - } -} diff --git a/lexicons/com/atproto/repo/listRecords.json b/lexicons/com/atproto/repo/listRecords.json deleted file mode 100644 index bc91c95..0000000 --- a/lexicons/com/atproto/repo/listRecords.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "lexicon": 1, - "id": "com.atproto.repo.listRecords", - "defs": { - "main": { - "type": "query", - "description": "List a range of records in a repository, matching a specific collection. Does not require auth.", - "parameters": { - "type": "params", - "required": ["repo", "collection"], - "properties": { - "repo": { - "type": "string", - "format": "at-identifier", - "description": "The handle or DID of the repo." - }, - "collection": { - "type": "string", - "format": "nsid", - "description": "The NSID of the record type." - }, - "limit": { - "type": "integer", - "minimum": 1, - "maximum": 100, - "default": 50, - "description": "The number of records to return." - }, - "cursor": { "type": "string" }, - "rkeyStart": { - "type": "string", - "description": "DEPRECATED: The lowest sort-ordered rkey to start from (exclusive)" - }, - "rkeyEnd": { - "type": "string", - "description": "DEPRECATED: The highest sort-ordered rkey to stop at (exclusive)" - }, - "reverse": { - "type": "boolean", - "description": "Flag to reverse the order of the returned records." - } - } - }, - "output": { - "encoding": "application/json", - "schema": { - "type": "object", - "required": ["records"], - "properties": { - "cursor": { "type": "string" }, - "records": { - "type": "array", - "items": { "type": "ref", "ref": "#record" } - } - } - } - } - }, - "record": { - "type": "object", - "required": ["uri", "cid", "value"], - "properties": { - "uri": { "type": "string", "format": "at-uri" }, - "cid": { "type": "string", "format": "cid" }, - "value": { "type": "unknown" } - } - } - } -} diff --git a/lexicons/com/atproto/repo/putRecord.json b/lexicons/com/atproto/repo/putRecord.json deleted file mode 100644 index 9a841f6..0000000 --- a/lexicons/com/atproto/repo/putRecord.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "lexicon": 1, - "id": "com.atproto.repo.putRecord", - "defs": { - "main": { - "type": "procedure", - "description": "Write a repository record, creating or updating it as needed. Requires auth, implemented by PDS.", - "input": { - "encoding": "application/json", - "schema": { - "type": "object", - "required": ["repo", "collection", "rkey", "record"], - "nullable": ["swapRecord"], - "properties": { - "repo": { - "type": "string", - "format": "at-identifier", - "description": "The handle or DID of the repo (aka, current account)." - }, - "collection": { - "type": "string", - "format": "nsid", - "description": "The NSID of the record collection." - }, - "rkey": { - "type": "string", - "description": "The Record Key.", - "maxLength": 15 - }, - "validate": { - "type": "boolean", - "description": "Can be set to 'false' to skip Lexicon schema validation of record data, 'true' to require it, or leave unset to validate only for known Lexicons." - }, - "record": { - "type": "unknown", - "description": "The record to write." - }, - "swapRecord": { - "type": "string", - "format": "cid", - "description": "Compare and swap with the previous record by CID. WARNING: nullable and optional field; may cause problems with golang implementation" - }, - "swapCommit": { - "type": "string", - "format": "cid", - "description": "Compare and swap with the previous commit by CID." - } - } - } - }, - "output": { - "encoding": "application/json", - "schema": { - "type": "object", - "required": ["uri", "cid"], - "properties": { - "uri": { "type": "string", "format": "at-uri" }, - "cid": { "type": "string", "format": "cid" }, - "commit": { - "type": "ref", - "ref": "com.atproto.repo.defs#commitMeta" - }, - "validationStatus": { - "type": "string", - "knownValues": ["valid", "unknown"] - } - } - } - }, - "errors": [{ "name": "InvalidSwap" }] - } - } -} diff --git a/lexicons/com/atproto/repo/strongRef.json b/lexicons/com/atproto/repo/strongRef.json deleted file mode 100644 index cb79625..0000000 --- a/lexicons/com/atproto/repo/strongRef.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "lexicon": 1, - "id": "com.atproto.repo.strongRef", - "description": "A URI with a content-hash fingerprint.", - "defs": { - "main": { - "type": "object", - "required": ["uri", "cid"], - "properties": { - "uri": { "type": "string", "format": "at-uri" }, - "cid": { "type": "string", "format": "cid" } - } - } - } -} diff --git a/lexicons/com/atproto/repo/uploadBlob.json b/lexicons/com/atproto/repo/uploadBlob.json deleted file mode 100644 index 547a995..0000000 --- a/lexicons/com/atproto/repo/uploadBlob.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "lexicon": 1, - "id": "com.atproto.repo.uploadBlob", - "defs": { - "main": { - "type": "procedure", - "description": "Upload a new blob, to be referenced from a repository record. The blob will be deleted if it is not referenced within a time window (eg, minutes). Blob restrictions (mimetype, size, etc) are enforced when the reference is created. Requires auth, implemented by PDS.", - "input": { - "encoding": "*/*" - }, - "output": { - "encoding": "application/json", - "schema": { - "type": "object", - "required": ["blob"], - "properties": { - "blob": { "type": "blob" } - } - } - } - } - } -} diff --git a/patching/120-ozone-runtimeEnvVars.diff b/patching/120-ozone-runtimeEnvVars.diff new file mode 100644 index 0000000..4f369a8 --- /dev/null +++ b/patching/120-ozone-runtimeEnvVars.diff @@ -0,0 +1,119 @@ +diff --git a/app/layout.tsx b/app/layout.tsx +index bfc3470..9350629 100644 +--- a/app/layout.tsx ++++ b/app/layout.tsx +@@ -5,6 +5,7 @@ import 'yet-another-react-lightbox/styles.css' + import 'yet-another-react-lightbox/plugins/thumbnails.css' + import 'yet-another-react-lightbox/plugins/captions.css' + import { ToastContainer } from 'react-toastify' ++import { PublicEnvScript } from 'next-runtime-env'; + + import { Shell } from '@/shell/Shell' + import { CommandPaletteRoot } from '@/shell/CommandPalette/Root' +@@ -36,6 +37,7 @@ export default function RootLayout({ + isDarkModeEnabled() ? 'dark' : '' + }`} + > ++ + Ozone + + ++ ++ + + blueSkyUrlMatcher.test(url) + +diff --git a/package.json b/package.json +index 8919841..750dce9 100644 +--- a/package.json ++++ b/package.json +@@ -37,6 +37,7 @@ + "kbar": "^0.1.0-beta.45", + "lande": "^1.0.10", + "next": "15.2.4", ++ "next-runtime-env": "^3.2.1", + "react": "19.1.0", + "react-dom": "19.1.0", + "react-dropzone": "^14.3.5", diff --git a/patching/121-ozone-constants-fix.patch b/patching/121-ozone-constants-fix.patch new file mode 100644 index 0000000..42ba11d --- /dev/null +++ b/patching/121-ozone-constants-fix.patch @@ -0,0 +1,99 @@ +--- a/lib/constants.ts ++++ b/lib/constants.ts +@@ -1,29 +1,32 @@ ++import { env } from 'next-runtime-env'; ++ + export const OAUTH_SCOPE = 'atproto transition:generic transition:chat.bsky' + + export const OZONE_SERVICE_DID = +- process.env.NEXT_PUBLIC_OZONE_SERVICE_DID || undefined ++ env('NEXT_PUBLIC_OZONE_SERVICE_DID') || undefined + + export const OZONE_PUBLIC_URL = +- process.env.NEXT_PUBLIC_OZONE_PUBLIC_URL || undefined ++ env('NEXT_PUBLIC_OZONE_PUBLIC_URL') || undefined + + export const PLC_DIRECTORY_URL = +- process.env.NEXT_PUBLIC_PLC_DIRECTORY_URL || ++ env('NEXT_PUBLIC_PLC_DIRECTORY_URL') || + (process.env.NODE_ENV === 'development' + ? 'http://localhost:2582' + : 'https://plc.directory') + +-export const QUEUE_CONFIG = process.env.NEXT_PUBLIC_QUEUE_CONFIG || '{}' ++export const QUEUE_CONFIG = env('NEXT_PUBLIC_QUEUE_CONFIG') || '{}' + +-export const QUEUE_SEED = process.env.NEXT_PUBLIC_QUEUE_SEED || '' ++export const QUEUE_SEED = env('NEXT_PUBLIC_QUEUE_SEED') || '' + ++export const SOCIAL_APP_DOMAIN = env('NEXT_PUBLIC_SOCIAL_APP_DOMAIN') || 'bsky.app' + export const SOCIAL_APP_URL = +- process.env.NEXT_PUBLIC_SOCIAL_APP_URL || ++ env('NEXT_PUBLIC_SOCIAL_APP_URL') || + (process.env.NODE_ENV === 'development' + ? 'http://localhost:2584' +- : 'https://bsky.app') ++ : `https://${SOCIAL_APP_DOMAIN}`) + + export const HANDLE_RESOLVER_URL = +- process.env.NEXT_PUBLIC_HANDLE_RESOLVER_URL || ++ env('NEXT_PUBLIC_HANDLE_RESOLVER_URL') || + (process.env.NODE_ENV === 'development' + ? 'http://localhost:2584' + : 'https://api.bsky.app') +@@ -36,25 +39,25 @@ + + export const NEW_ACCOUNT_MARKER_THRESHOLD_IN_DAYS = process.env + .NEXT_PUBLIC_NEW_ACCOUNT_MARKER_THRESHOLD_IN_DAYS +- ? parseInt(process.env.NEXT_PUBLIC_NEW_ACCOUNT_MARKER_THRESHOLD_IN_DAYS) ++ ? parseInt(env('NEXT_PUBLIC_NEW_ACCOUNT_MARKER_THRESHOLD_IN_DAYS')) + : 7 + + export const YOUNG_ACCOUNT_MARKER_THRESHOLD_IN_DAYS = process.env + .NEXT_PUBLIC_YOUNG_ACCOUNT_MARKER_THRESHOLD_IN_DAYS +- ? parseInt(process.env.NEXT_PUBLIC_YOUNG_ACCOUNT_MARKER_THRESHOLD_IN_DAYS) ++ ? parseInt(env('NEXT_PUBLIC_YOUNG_ACCOUNT_MARKER_THRESHOLD_IN_DAYS')) + : 30 + + export const DOMAINS_ALLOWING_EMAIL_COMMUNICATION = ( +- process.env.NEXT_PUBLIC_DOMAINS_ALLOWING_EMAIL_COMMUNICATION || '' ++ env('NEXT_PUBLIC_DOMAINS_ALLOWING_EMAIL_COMMUNICATION') || '' + ).split(',') + + export const HIGH_PROFILE_FOLLOWER_THRESHOLD = process.env + .NEXT_PUBLIC_HIGH_PROFILE_FOLLOWER_THRESHOLD +- ? parseInt(process.env.NEXT_PUBLIC_HIGH_PROFILE_FOLLOWER_THRESHOLD) ++ ? parseInt(env('NEXT_PUBLIC_HIGH_PROFILE_FOLLOWER_THRESHOLD')) + : Infinity + + export const FALLBACK_VIDEO_URL = ( +- process.env.NEXT_PUBLIC_FALLBACK_VIDEO_URL || '' ++ env('NEXT_PUBLIC_FALLBACK_VIDEO_URL') || '' + ).split(':') + + // strike to account suspension duration mapping (in hours) +@@ -87,18 +90,18 @@ + + export const STRIKE_TO_SUSPENSION_DURATION_IN_HOURS = + parseStrikeSuspensionConfig( +- process.env.NEXT_PUBLIC_STRIKE_SUSPENSION_CONFIG || '', ++ env('NEXT_PUBLIC_STRIKE_SUSPENSION_CONFIG') || '', + ) + + export const AUTOMATED_ACTION_EMAIL_IDS = { + warningWithTakedown: +- process.env.NEXT_PUBLIC_WARNING_WITH_TAKEDOWN_EMAIL_TEMPLATE_ID, ++ env('NEXT_PUBLIC_WARNING_WITH_TAKEDOWN_EMAIL_TEMPLATE_ID'), + suspensionWithTakedown: +- process.env.NEXT_PUBLIC_SUSPENSION_WITH_TAKEDOWN_EMAIL_TEMPLATE_ID, ++ env('NEXT_PUBLIC_SUSPENSION_WITH_TAKEDOWN_EMAIL_TEMPLATE_ID'), + suspensionWithoutTakedown: +- process.env.NEXT_PUBLIC_SUSPENSION_WITHOUT_TAKEDOWN_EMAIL_TEMPLATE_ID, ++ env('NEXT_PUBLIC_SUSPENSION_WITHOUT_TAKEDOWN_EMAIL_TEMPLATE_ID'), + permanentTakedown: +- process.env.NEXT_PUBLIC_PERMANENT_TAKEDOWN_EMAIL_TEMPLATE_ID, ++ env('NEXT_PUBLIC_PERMANENT_TAKEDOWN_EMAIL_TEMPLATE_ID'), + takedownWithoutStrike: +- process.env.NEXT_PUBLIC_TAKEDOWN_WITHOUT_STRIKE_EMAIL_TEMPLATE_ID, ++ env('NEXT_PUBLIC_TAKEDOWN_WITHOUT_STRIKE_EMAIL_TEMPLATE_ID'), + } diff --git a/patching/122-ozone-enable-daemon.diff b/patching/122-ozone-enable-daemon.diff new file mode 100644 index 0000000..3b783df --- /dev/null +++ b/patching/122-ozone-enable-daemon.diff @@ -0,0 +1,82 @@ +diff --git a/service/index.js b/service/index.js +index 943c281..7721cd9 100644 +--- a/service/index.js ++++ b/service/index.js +@@ -1,5 +1,7 @@ + const next = require('next') +-const { ++const ozone = require('@atproto/ozone') ++/* ++{ + readEnv, + httpLogger, + envToCfg, +@@ -7,6 +9,7 @@ const { + OzoneService, + Database, + } = require('@atproto/ozone') ++*/ + const pkg = require('@atproto/ozone/package.json') + + async function main() { +@@ -16,37 +19,48 @@ async function main() { + const frontendHandler = frontend.getRequestHandler() + await frontend.prepare() + // backend +- const env = readEnv() ++ const env = ozone.readEnv() + env.version ??= pkg.version +- const config = envToCfg(env) +- const secrets = envToSecrets(env) ++ const config = ozone.envToCfg(env) ++ const secrets = ozone.envToSecrets(env) + const migrate = process.env.OZONE_DB_MIGRATE === '1' + if (migrate) { +- const db = new Database({ ++ const db = new ozone.Database({ + url: config.db.postgresUrl, + schema: config.db.postgresSchema, + }) + await db.migrateToLatestOrThrow() + await db.close() + } +- const ozone = await OzoneService.create(config, secrets) ++ const server = await ozone.OzoneService.create(config, secrets) + // setup handlers +- ozone.app.get('/.well-known/ozone-metadata.json', (_req, res) => { ++ server.app.get('/.well-known/ozone-metadata.json', (_req, res) => { + return res.json({ +- did: ozone.ctx.cfg.service.did, +- url: ozone.ctx.cfg.service.publicUrl, +- publicKey: ozone.ctx.signingKey.did(), ++ did: server.ctx.cfg.service.did, ++ url: server.ctx.cfg.service.publicUrl, ++ publicKey: server.ctx.signingKey.did(), + }) + }) + // Note: We must use `use()` here. This should be the last middleware. +- ozone.app.use((req, res) => { ++ server.app.use((req, res) => { + void frontendHandler(req, res, undefined) + }) + // run +- const httpServer = await ozone.start() ++ const httpServer = await server.start() ++ // starts: involve ops from atproto/packages/dev-env/src/ozone.ts >>> ++ ozone.httpLogger.info('starts ozone daemon') ++ const daemon = await ozone.OzoneDaemon.create(config, secrets) ++ await daemon.start() ++ //if (process.env.OZONE_ENABLE_EVENT_REVERSER != 'true') // atproto/services/ozone/daemon.js doesn't stop eventReverser ++ //{ ++ // ozone.httpLogger.info('disable ozone daemon eventReverser') ++ // await daemon.ctx.eventReverser.destroy() ++ //} ++ // ends: involve ops from atproto/packages/dev-env/src/ozone.ts <<< ++ + /** @type {import('net').AddressInfo} */ + const addr = httpServer.address() +- httpLogger.info(`Ozone is running at http://localhost:${addr.port}`) ++ ozone.httpLogger.info(`Ozone is running at http://localhost:${addr.port}`) + } + + main().catch(console.error) diff --git a/patching/130-atproto-ozone-enable-daemon-v2.patch b/patching/130-atproto-ozone-enable-daemon-v2.patch new file mode 100644 index 0000000..792c655 --- /dev/null +++ b/patching/130-atproto-ozone-enable-daemon-v2.patch @@ -0,0 +1,28 @@ +--- a/services/ozone/api.js ++++ b/services/ozone/api.js +@@ -23,6 +23,7 @@ + Database, + OzoneService, + envToCfg, ++ OzoneDaemon, + envToSecrets, + httpLogger, + readEnv, +@@ -79,10 +80,17 @@ + + httpLogger.info('ozone is running') + ++ // Start OzoneDaemon for label events ++ httpLogger.info('starting ozone daemon') ++ const daemon = await OzoneDaemon.create(cfg, secrets) ++ await daemon.start() ++ httpLogger.info('ozone daemon is running') ++ + // Graceful shutdown (see also https://aws.amazon.com/blogs/containers/graceful-shutdowns-with-ecs/) + process.on('SIGTERM', async () => { + httpLogger.info('ozone is stopping') + ++ await daemon.destroy() + await ozone.destroy() + + httpLogger.info('ozone is stopped') diff --git a/patching/130-atproto-ozone-enable-daemon.patch b/patching/130-atproto-ozone-enable-daemon.patch new file mode 100644 index 0000000..7a10d3d --- /dev/null +++ b/patching/130-atproto-ozone-enable-daemon.patch @@ -0,0 +1,33 @@ +--- a/services/ozone/api.js ++++ b/services/ozone/api.js +@@ -20,6 +20,7 @@ const { + MultiImageInvalidator, + } = require('@atproto/aws') + const { + Database, + OzoneService, ++ OzoneDaemon, + envToCfg, + envToSecrets, + httpLogger, +@@ -76,10 +77,17 @@ const main = async () => { + const ozone = await OzoneService.create(cfg, secrets, { imgInvalidator }) + + await ozone.start() + + httpLogger.info('ozone is running') + ++ // Start OzoneDaemon for label events ++ httpLogger.info('starting ozone daemon') ++ const daemon = await OzoneDaemon.create(cfg, secrets) ++ await daemon.start() ++ httpLogger.info('ozone daemon is running') ++ + // Graceful shutdown (see also https://aws.amazon.com/blogs/containers/graceful-shutdowns-with-ecs/) + process.on('SIGTERM', async () => { + httpLogger.info('ozone is stopping') + ++ await daemon.destroy() + await ozone.destroy() + + httpLogger.info('ozone is stopped') diff --git a/patching/105-atproto-services-for-docker.diff b/patching/4367-atproto-services-bsky-api.diff similarity index 52% rename from patching/105-atproto-services-for-docker.diff rename to patching/4367-atproto-services-bsky-api.diff index c428d6f..f887230 100644 --- a/patching/105-atproto-services-for-docker.diff +++ b/patching/4367-atproto-services-bsky-api.diff @@ -1,14 +1,89 @@ -diff --git a/services/bsky/api.js b/services/bsky/api.js -index 56c769b9d..5d14c0057 100644 ---- a/services/bsky/api.js -+++ b/services/bsky/api.js -@@ -44,19 +44,62 @@ const assert = require('node:assert') +--- a/services/bsky/api.js 2025-12-03 11:04:54 ++++ b/services/bsky/api.js 2025-12-03 11:00:02 +@@ -1,62 +1,105 @@ + /* eslint-env node */ + /* eslint-disable import/order */ +- ++// https://github.com/bluesky-social/atproto/blob/main/services/bsky/api.js + 'use strict' + +-const dd = require('dd-trace') ++//const dd = require('dd-trace') ++// ++//dd.tracer ++// .init() ++// .use('http2', { ++// client: true, // calls into dataplane ++// server: false, ++// }) ++// .use('express', { ++// hooks: { ++// request: (span, req) => { ++// maintainXrpcResource(span, req) ++// }, ++// }, ++// }) + +-dd.tracer +- .init() +- .use('http2', { +- client: true, // calls into dataplane +- server: false, +- }) +- .use('express', { +- hooks: { +- request: (span, req) => { +- maintainXrpcResource(span, req) +- }, +- }, +- }) +- + // modify tracer in order to track calls to dataplane as a service with proper resource names + const DATAPLANE_PREFIX = '/bsky.Service/' +-const origStartSpan = dd.tracer._tracer.startSpan +-dd.tracer._tracer.startSpan = function (name, options) { +- if ( +- name !== 'http.request' || +- options?.tags?.component !== 'http2' || +- !options?.tags?.['http.url'] +- ) { +- return origStartSpan.call(this, name, options) +- } +- const uri = new URL(options.tags['http.url']) +- if (!uri.pathname.startsWith(DATAPLANE_PREFIX)) { +- return origStartSpan.call(this, name, options) +- } +- options.tags['service.name'] = 'dataplane-bsky' +- options.tags['resource.name'] = uri.pathname.slice(DATAPLANE_PREFIX.length) +- return origStartSpan.call(this, name, options) +-} ++//const origStartSpan = dd.tracer._tracer.startSpan ++//dd.tracer._tracer.startSpan = function (name, options) { ++// if ( ++// name !== 'http.request' || ++// options?.tags?.component !== 'http2' || ++// !options?.tags?.['http.url'] ++// ) { ++// return origStartSpan.call(this, name, options) ++// } ++// const uri = new URL(options.tags['http.url']) ++// if (!uri.pathname.startsWith(DATAPLANE_PREFIX)) { ++// return origStartSpan.call(this, name, options) ++// } ++// options.tags['service.name'] = 'dataplane-bsky' ++// options.tags['resource.name'] = uri.pathname.slice(DATAPLANE_PREFIX.length) ++// return origStartSpan.call(this, name, options) ++//} + + // Tracer code above must come before anything else + const assert = require('node:assert') const cluster = require('node:cluster') const path = require('node:path') - + -const { BskyAppView, ServerConfig } = require('@atproto/bsky') -+const bsky = require('@atproto/bsky') // import all bsky features - const { Secp256k1Keypair } = require('@atproto/crypto') +-const { Secp256k1Keypair } = require('@atproto/crypto') ++const bsky = require('/app/packages/bsky') // import all bsky features ++const { Secp256k1Keypair } = require('/app/packages/crypto') const main = async () => { const env = getEnv() @@ -70,7 +145,7 @@ index 56c769b9d..5d14c0057 100644 } process.on('SIGTERM', shutdown) process.on('disconnect', shutdown) // when clustering -@@ -64,6 +107,12 @@ const main = async () => { +@@ -64,6 +107,12 @@ const getEnv = () => ({ serviceSigningKey: process.env.BSKY_SERVICE_SIGNING_KEY || undefined, diff --git a/patching/4367-atproto-services-pds-index.diff b/patching/4367-atproto-services-pds-index.diff new file mode 100644 index 0000000..a8165f8 --- /dev/null +++ b/patching/4367-atproto-services-pds-index.diff @@ -0,0 +1,20 @@ +--- a/services/pds/index.js 2025-12-03 11:04:54 ++++ b/services/pds/index.js 2025-12-02 22:11:39 +@@ -1,5 +1,5 @@ + /* eslint-env node */ +- ++// https://github.com/bluesky-social/atproto/blob/main/services/pds/index.js + 'use strict' + + const { +@@ -8,8 +8,8 @@ + envToSecrets, + httpLogger, + readEnv, +-} = require('@atproto/pds') +-const pkg = require('@atproto/pds/package.json') ++} = require('/app/packages/pds') ++const pkg = require('/app/packages/pds/package.json') + + const main = async () => { + const env = readEnv() diff --git a/patching/8980-social-app-disable-external-services.diff b/patching/8980-social-app-disable-external-services.diff new file mode 100644 index 0000000..74ffc22 --- /dev/null +++ b/patching/8980-social-app-disable-external-services.diff @@ -0,0 +1,17 @@ +--- a/src/state/geolocation/const.ts ++++ b/src/state/geolocation/const.ts +@@ -3,9 +3,10 @@ import {BAPP_CONFIG_DEV_URL, IS_DEV} from '#/env' + import {type Device} from '#/storage' + + export const IPCC_URL = `https://bsky.app/ipcc` +-export const BAPP_CONFIG_URL_PROD = `https://ip.bsky.app/config` +-export const BAPP_CONFIG_URL = IS_DEV +- ? (BAPP_CONFIG_DEV_URL ?? BAPP_CONFIG_URL_PROD) +- : BAPP_CONFIG_URL_PROD ++// Disabled for self-hosted environment to avoid CORS errors ++// export const BAPP_CONFIG_URL_PROD = `https://ip.bsky.app/config` ++// export const BAPP_CONFIG_URL = IS_DEV ++// ? (BAPP_CONFIG_DEV_URL ?? BAPP_CONFIG_URL_PROD) ++// : BAPP_CONFIG_URL_PROD ++export const BAPP_CONFIG_URL = null + export const GEOLOCATION_CONFIG_URL = BAPP_CONFIG_URL diff --git a/patching/8980-social-app-disable-proxy.diff b/patching/8980-social-app-disable-proxy.diff new file mode 100644 index 0000000..4bc454f --- /dev/null +++ b/patching/8980-social-app-disable-proxy.diff @@ -0,0 +1,44 @@ +diff --git a/src/state/session/agent.ts b/src/state/session/agent.ts +index 36d19299b..ba095436a 100644 +--- a/src/state/session/agent.ts ++++ b/src/state/session/agent.ts +@@ -39,7 +39,8 @@ export function createPublicAgent() { + configureModerationForGuest() // Side effect but only relevant for tests + + const agent = new BskyAppAgent({service: PUBLIC_BSKY_SERVICE}) +- agent.configureProxy(BLUESKY_PROXY_HEADER.get()) ++ // Disable proxy for self-hosted environments ++ // agent.configureProxy(BLUESKY_PROXY_HEADER.get()) + return agent + } + +@@ -77,7 +78,8 @@ export async function createAgentAndResume( + } + } + +- agent.configureProxy(BLUESKY_PROXY_HEADER.get()) ++ // Disable proxy for self-hosted environments ++ // agent.configureProxy(BLUESKY_PROXY_HEADER.get()) + + return agent.prepare(gates, moderation, onSessionChange) + } +@@ -112,7 +114,8 @@ export async function createAgentAndLogin( + const gates = tryFetchGates(account.did, 'prefer-fresh-gates') + const moderation = configureModerationForAccount(agent, account) + +- agent.configureProxy(BLUESKY_PROXY_HEADER.get()) ++ // Disable proxy for self-hosted environments ++ // agent.configureProxy(BLUESKY_PROXY_HEADER.get()) + + return agent.prepare(gates, moderation, onSessionChange) + } +@@ -201,7 +204,8 @@ export async function createAgentAndCreateAccount( + logger.error(e, {message: `session: failed snoozeEmailConfirmationPrompt`}) + } + +- agent.configureProxy(BLUESKY_PROXY_HEADER.get()) ++ // Disable proxy for self-hosted environments ++ // agent.configureProxy(BLUESKY_PROXY_HEADER.get()) + + return agent.prepare(gates, moderation, onSessionChange) + } diff --git a/repos_extra/frontpage/diff.patch b/repos_extra/frontpage/diff.patch deleted file mode 100644 index bd90bf7..0000000 --- a/repos_extra/frontpage/diff.patch +++ /dev/null @@ -1,499 +0,0 @@ -diff --git a/packages-rs/drainpipe/docker-compose.yml b/packages-rs/drainpipe/docker-compose.yml -index 0e1d2ca..d5e214a 100644 ---- a/packages-rs/drainpipe/docker-compose.yml -+++ b/packages-rs/drainpipe/docker-compose.yml -@@ -1,4 +1,3 @@ --version: "3" - services: - drainpipe: - build: -diff --git a/packages-rs/drainpipe/src/main.rs b/packages-rs/drainpipe/src/main.rs -index 21278a5..0a05d06 100644 ---- a/packages-rs/drainpipe/src/main.rs -+++ b/packages-rs/drainpipe/src/main.rs -@@ -76,7 +76,7 @@ async fn process(message: Vec, ctx: &mut Context) -> Result>(); - if !frontpage_ops.is_empty() { - process_frontpage_ops(&frontpage_ops, &commit, &ctx) -diff --git a/packages/frontpage/app/(app)/_components/post-card.tsx b/packages/frontpage/app/(app)/_components/post-card.tsx -index c0720e5..e619a5f 100644 ---- a/packages/frontpage/app/(app)/_components/post-card.tsx -+++ b/packages/frontpage/app/(app)/_components/post-card.tsx -@@ -83,7 +83,7 @@ export async function PostCard({ - votes={votes} - /> - --
-+
-

- -+
-+ {/*
*/} -
- - {/* eslint-disable-next-line @next/next/no-img-element */} -@@ -52,6 +53,8 @@ export default async function Layout({ - -
{children}
- -+
-+ {/* -
-

- Made by{" "} -@@ -59,10 +62,11 @@ export default async function Layout({ - href={`https://bsky.app/profile/${FRONTPAGE_ATPROTO_HANDLE}`} - className="font-medium text-indigo-600 hover:text-indigo-500 dark:text-indigo-400 dark:hover:text-indigo-300" - > -- @frontpage.fyi -+ @o.syui.ai - -

-
-+ */} -
- ); - } -@@ -141,8 +145,8 @@ async function LoginOrLogout() { - } - - return ( -- - ); - } -diff --git a/packages/frontpage/app/(app)/post/[postAuthor]/[postRkey]/[commentAuthor]/[commentRkey]/page.tsx b/packages/frontpage/app/(app)/post/[postAuthor]/[postRkey]/[commentAuthor]/[commentRkey]/page.tsx -index c9a2883..c50b02f 100644 ---- a/packages/frontpage/app/(app)/post/[postAuthor]/[postRkey]/[commentAuthor]/[commentRkey]/page.tsx -+++ b/packages/frontpage/app/(app)/post/[postAuthor]/[postRkey]/[commentAuthor]/[commentRkey]/page.tsx -@@ -30,7 +30,7 @@ export async function generateMetadata(props: { - description: - comment.status === "live" ? truncateText(comment.body, 47) : null, - alternates: { -- canonical: `https://frontpage.fyi${path}`, -+ canonical: `https://o.syui.ai${path}`, - }, - openGraph: - comment.status === "live" -@@ -40,7 +40,7 @@ export async function generateMetadata(props: { - type: "article", - publishedTime: comment.createdAt.toISOString(), - authors: [`@${handle}`], -- url: `https://frontpage.fyi${path}`, -+ url: `https://o.syui.ai${path}`, - images: [ - { - url: `${path}/og-image`, -diff --git a/packages/frontpage/app/(app)/post/[postAuthor]/[postRkey]/_lib/comment-client.tsx b/packages/frontpage/app/(app)/post/[postAuthor]/[postRkey]/_lib/comment-client.tsx -index 71dd664..954f499 100644 ---- a/packages/frontpage/app/(app)/post/[postAuthor]/[postRkey]/_lib/comment-client.tsx -+++ b/packages/frontpage/app/(app)/post/[postAuthor]/[postRkey]/_lib/comment-client.tsx -@@ -283,16 +283,12 @@ export function NewComment({ - ref={textAreaRef} - placeholder="Write a comment..." - disabled={isPending} -- className="resize-y flex-1" -+ className="" - /> -
-- --
-+
- {extraButton} -- -
-diff --git a/packages/frontpage/app/(app)/post/[postAuthor]/[postRkey]/layout.tsx b/packages/frontpage/app/(app)/post/[postAuthor]/[postRkey]/layout.tsx -index 517c871..ef73ecb 100644 ---- a/packages/frontpage/app/(app)/post/[postAuthor]/[postRkey]/layout.tsx -+++ b/packages/frontpage/app/(app)/post/[postAuthor]/[postRkey]/layout.tsx -@@ -29,7 +29,7 @@ export default async function Post(props: { - } - - return ( --
-+
- }) { - - return ( - <> -+ -+ {/* - }) { - /> - ))} -
-+ */} -+ -+ {params.postAuthor === "syui.ai" && (post.title.includes("live") || post.title.includes("video")) && ( -+
-+ -+
-+ -+ -+ {comments.map((comment) => ( -+ -+ ))} -+
-+
-+ )} -+ -+ {post.status === "live" ? ( -+ -+ ) : ( -+ -+ This post has been deleted -+ -+ Deleted posts cannot receive new comments. -+ -+ -+ )} -+
-+ {comments.map((comment) => ( -+ -+ ))} -+ -+
-+ - - ); - } -diff --git a/packages/frontpage/app/(auth)/login/page.tsx b/packages/frontpage/app/(auth)/login/page.tsx -index e3165f9..4d661ce 100644 ---- a/packages/frontpage/app/(auth)/login/page.tsx -+++ b/packages/frontpage/app/(auth)/login/page.tsx -@@ -14,17 +14,15 @@ export default async function LoginPage() { -
-
-

-- Sign in to Frontpage -+ Login with atproto -

-

-- Don't have an account?{" "} - -- Sign up on Bluesky -- -- , then return here to login. -+ Bluesky -+ oauth login -

-
- -diff --git a/packages/frontpage/app/api/receive_hook/route.ts b/packages/frontpage/app/api/receive_hook/route.ts -index 04bda27..9feb136 100644 ---- a/packages/frontpage/app/api/receive_hook/route.ts -+++ b/packages/frontpage/app/api/receive_hook/route.ts -@@ -96,7 +96,7 @@ export async function POST(request: Request) { - }); - } - -- if (collection === "fyi.unravel.frontpage.vote") { -+ if (collection === "ai.syui.o.vote") { - if (op.action === "create") { - const hydratedRecord = await atprotoGetRecord({ - serviceEndpoint: service, -diff --git a/packages/frontpage/app/globals.css b/packages/frontpage/app/globals.css -index 9abc86b..e22dba5 100644 ---- a/packages/frontpage/app/globals.css -+++ b/packages/frontpage/app/globals.css -@@ -13,8 +13,12 @@ - --popover: 0 0% 100%; - --popover-foreground: 222.2 84% 4.9%; - -+ /* - --primary: 222.2 47.4% 11.2%; -- --primary-foreground: 210 40% 98%; -+ --primary-foreground: 210 40% 98%; */ -+ -+ --primary: 210 100% 50%; /* HSLカラーで青色を定義 */ -+ --primary-foreground: 0 0% 100%; /* 白色のテキスト */ - - --secondary: 210 40% 96.1%; - --secondary-foreground: 222.2 47.4% 11.2%; -@@ -67,8 +71,12 @@ - --popover: 222.2 84% 4.9%; - --popover-foreground: 210 40% 98%; - -- --primary: 210 40% 98%; -- --primary-foreground: 222.2 47.4% 11.2%; -+ /*--primary: 210 40% 98%; -+ *--primary-foreground: 222.2 47.4% 11.2%;*/ -+ -+ /* ダークモード用に少し明るい青 */ -+ --primary: 210 100% 60%; -+ --primary-foreground: 0 0% 100%; - - --secondary: 217.2 32.6% 17.5%; - --secondary-foreground: 210 40% 98%; -diff --git a/packages/frontpage/app/layout.tsx b/packages/frontpage/app/layout.tsx -index e8b5a39..a9fa945 100644 ---- a/packages/frontpage/app/layout.tsx -+++ b/packages/frontpage/app/layout.tsx -@@ -22,13 +22,13 @@ const sourceSans = Source_Sans_3({ - }); - - export const metadata: Metadata = { -- title: "Frontpage", -+ title: "o.syui.ai", - description: "A federated link aggregator. Your frontpage to the internet.", - openGraph: { - title: "Frontpage", - description: "Your frontpage to the internet.", - type: "website", -- siteName: "frontpage.fyi", -+ siteName: "o.syui.ai", - }, - }; - -@@ -53,11 +53,7 @@ export default function Layout({ children }: { children: React.ReactNode }) { - - - --