diff --git a/.env.example b/.env.example index e87f4563..f821cb41 100644 --- a/.env.example +++ b/.env.example @@ -38,11 +38,5 @@ SYNDICATE_MOUNT_PATH=/syndicate BLUESKY_HANDLE= BLUESKY_PASSWORD= -# Mastodon syndicator settings -# MASTODON_USER should be your username without @ -MASTODON_URL= -MASTODON_USER= -MASTODON_ACCESS_TOKEN= - # Poll interval for webmention-sender (seconds). Long enough for deploys to complete. WEBMENTION_SENDER_POLL_INTERVAL=600 diff --git a/indiekit.config.mjs b/indiekit.config.mjs index a0c625b4..e5eb0a19 100644 --- a/indiekit.config.mjs +++ b/indiekit.config.mjs @@ -84,14 +84,6 @@ const blueskyHandle = (process.env.BLUESKY_HANDLE || "") .trim() .replace(/^@+/, ""); const blueskyPassword = process.env.BLUESKY_PASSWORD || ""; -const mastodonUrl = process.env.MASTODON_URL || "https://troet.cafe"; -const mastodonUser = ( - process.env.MASTODON_USER || process.env.MASTODON_USERNAME || "" -) - .trim() - .replace(/^@+/, ""); -const mastodonAccessToken = - process.env.MASTODON_ACCESS_TOKEN || process.env.MASTODON_TOKEN || ""; const syndicateMountPath = process.env.SYNDICATE_MOUNT_PATH || "/syndicate"; const publicationBaseUrl = ( @@ -327,7 +319,6 @@ export default { "@indiekit/post-type-repost", "@rmdes/indiekit-post-type-page", "@rmdes/indiekit-syndicator-bluesky", - "@rmdes/indiekit-syndicator-mastodon", "@rmdes/indiekit-syndicator-indienews", "@rmdes/indiekit-preset-eleventy", "@rmdes/indiekit-endpoint-github", @@ -367,17 +358,6 @@ export default { handle: blueskyHandle, password: blueskyPassword, }, - "@rmdes/indiekit-syndicator-mastodon": { - url: mastodonUrl, - user: mastodonUser, - accessToken: mastodonAccessToken, - // AP endpoint sends native Like/Announce activities; skip the redundant - // "❤️ URL" / "🔁 URL" status posts for external fediverse URLs. - // Native same-instance favourites/reblogs still work (needs write:favourites - // + write:statuses scope on the token). - syndicateExternalLikes: false, - syndicateExternalReposts: false, - }, "@indiekit/endpoint-syndicate": { mountPath: syndicateMountPath, }, diff --git a/package-lock.json b/package-lock.json index 966a9a9a..473b77e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,7 +33,6 @@ "@rmdes/indiekit-preset-eleventy": "^1.0.0-beta.33", "@rmdes/indiekit-syndicator-bluesky": "^1.0.19", "@rmdes/indiekit-syndicator-indienews": "^1.0.1", - "@rmdes/indiekit-syndicator-mastodon": "^1.0.8", "dotenv": "^17.3.1", "mongodb": "^7.1.0", "node-gyp": "^12.2.0" @@ -3106,21 +3105,6 @@ "node": ">=20" } }, - "node_modules/@rmdes/indiekit-syndicator-mastodon": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@rmdes/indiekit-syndicator-mastodon/-/indiekit-syndicator-mastodon-1.0.8.tgz", - "integrity": "sha512-5Ikq/YH1EH/7TwSiSrTCuJFanyZqf4j7sDyEJ/+/OAbiyDEpWSR1wZz2yzMoWzwI1XuPJu8pU+cQGbuB/fs6OA==", - "license": "MIT", - "dependencies": { - "html-to-text": "^9.0.0", - "masto": "^6.0.0" - }, - "peerDependencies": { - "@indiekit/error": "^1.0.0-beta.25", - "@indiekit/indiekit": "1.x", - "@indiekit/util": "^1.0.0-beta.25" - } - }, "node_modules/@selderee/plugin-htmlparser2": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz", @@ -3563,16 +3547,6 @@ "node": ">=6" } }, - "node_modules/camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "license": "MIT", - "dependencies": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, "node_modules/camelcase": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-9.0.0.tgz", @@ -3612,37 +3586,6 @@ "canonicalize": "bin/canonicalize.js" } }, - "node_modules/capital-case": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", - "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", - "license": "MIT", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3", - "upper-case-first": "^2.0.2" - } - }, - "node_modules/change-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz", - "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==", - "license": "MIT", - "dependencies": { - "camel-case": "^4.1.2", - "capital-case": "^1.0.4", - "constant-case": "^3.0.4", - "dot-case": "^3.0.4", - "header-case": "^2.0.4", - "no-case": "^3.0.4", - "param-case": "^3.0.4", - "pascal-case": "^3.1.2", - "path-case": "^3.0.4", - "sentence-case": "^3.0.4", - "snake-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, "node_modules/cheerio": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz", @@ -3933,17 +3876,6 @@ "node": "^14.18.0 || >=16.10.0" } }, - "node_modules/constant-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", - "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==", - "license": "MIT", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3", - "upper-case": "^2.0.2" - } - }, "node_modules/content-disposition": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", @@ -4358,16 +4290,6 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, - "node_modules/dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "license": "MIT", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, "node_modules/dotenv": { "version": "17.3.1", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.3.1.tgz", @@ -4597,12 +4519,6 @@ "node": ">= 0.6" } }, - "node_modules/events-to-async": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/events-to-async/-/events-to-async-2.0.2.tgz", - "integrity": "sha512-WzI6m/SU+F38t2tejHh6IQuQkNZ0dMOmSEmODJb9czaeMYtQ5FVZ+b6DOHr3hC6hNKNnn9CwDUN8mJiAkWSI9Q==", - "license": "MIT" - }, "node_modules/execa": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", @@ -5087,16 +5003,6 @@ "he": "bin/he" } }, - "node_modules/header-case": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz", - "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==", - "license": "MIT", - "dependencies": { - "capital-case": "^1.0.4", - "tslib": "^2.0.3" - } - }, "node_modules/hono": { "version": "4.12.7", "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.7.tgz", @@ -5572,15 +5478,6 @@ "integrity": "sha512-yLEMkBbLZTlVQqOnQ4FiMujR6T4DEcCb1xizmvXS+OxuhwcbtynoosRzdMA69zZCShCNAbi+gJ71FxZBBXx1SA==", "license": "MIT" }, - "node_modules/isomorphic-ws": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz", - "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==", - "license": "MIT", - "peerDependencies": { - "ws": "*" - } - }, "node_modules/jiti": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", @@ -6169,15 +6066,6 @@ "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==", "license": "MIT" }, - "node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "license": "MIT", - "dependencies": { - "tslib": "^2.0.3" - } - }, "node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", @@ -6316,19 +6204,6 @@ "node": ">= 12" } }, - "node_modules/masto": { - "version": "6.10.4", - "resolved": "https://registry.npmjs.org/masto/-/masto-6.10.4.tgz", - "integrity": "sha512-TqIkWaZa884j9jik39efsv6mdpgalUElwiGLLPHevLlIuCSnGjapGC++VovlQvvVV6O5e4ce/gzWNy17cF6PHg==", - "license": "MIT", - "dependencies": { - "change-case": "^4.1.2", - "events-to-async": "^2.0.1", - "isomorphic-ws": "^5.0.0", - "ts-custom-error": "^3.3.1", - "ws": "^8.18.0" - } - }, "node_modules/math-interval-parser": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/math-interval-parser/-/math-interval-parser-2.0.1.tgz", @@ -6745,16 +6620,6 @@ "resolved": "https://registry.npmjs.org/newbase60/-/newbase60-1.3.1.tgz", "integrity": "sha512-2bjwvv8ytc4YQXXnV7lSz7yzQv01eYcdhhX/lo3OWkXgRSxfbbQb922s+6uiC4i5HbNlNu8Vtu9mSZ/xKRaTkg==" }, - "node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "license": "MIT", - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, "node_modules/node-addon-api": { "version": "8.6.0", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-8.6.0.tgz", @@ -7065,16 +6930,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "license": "MIT", - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -7182,26 +7037,6 @@ "node": ">= 0.8" } }, - "node_modules/pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "license": "MIT", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/path-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz", - "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==", - "license": "MIT", - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -7775,17 +7610,6 @@ "url": "https://opencollective.com/express" } }, - "node_modules/sentence-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz", - "integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==", - "license": "MIT", - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3", - "upper-case-first": "^2.0.2" - } - }, "node_modules/serve-static": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", @@ -7991,16 +7815,6 @@ "npm": ">= 3.0.0" } }, - "node_modules/snake-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", - "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", - "license": "MIT", - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, "node_modules/snakecase-keys": { "version": "9.0.2", "resolved": "https://registry.npmjs.org/snakecase-keys/-/snakecase-keys-9.0.2.tgz", @@ -8340,15 +8154,6 @@ "node": ">=18" } }, - "node_modules/ts-custom-error": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/ts-custom-error/-/ts-custom-error-3.3.1.tgz", - "integrity": "sha512-5OX1tzOjxWEgsr/YEUWSuPrQ00deKLh6D7OTWcvNHm12/7QPyRh8SYpyWvA4IZv8H/+GQWQEh/kwo95Q9OVW1A==", - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -8727,24 +8532,6 @@ "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", "license": "MIT" }, - "node_modules/upper-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz", - "integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==", - "license": "MIT", - "dependencies": { - "tslib": "^2.0.3" - } - }, - "node_modules/upper-case-first": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz", - "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", - "license": "MIT", - "dependencies": { - "tslib": "^2.0.3" - } - }, "node_modules/uqr": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/uqr/-/uqr-0.1.2.tgz", diff --git a/package.json b/package.json index 0fd13bd8..54b426b6 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,8 @@ "description": "", "main": "index.js", "scripts": { - "postinstall": "xattr -w com.apple.fileprovider.ignore#P 1 node_modules 2>/dev/null || true && node scripts/patch-lightningcss.mjs && node scripts/patch-endpoint-media-scope.mjs && node scripts/patch-endpoint-media-sharp-runtime.mjs && node scripts/patch-frontend-sharp-runtime.mjs && node scripts/patch-endpoint-files-upload-route.mjs && node scripts/patch-endpoint-files-upload-locales.mjs && node scripts/patch-endpoint-activitypub-locales.mjs && node scripts/patch-endpoint-homepage-locales.mjs && node scripts/patch-endpoint-homepage-identity-defaults.mjs && node scripts/patch-federation-unlisted-guards.mjs && node scripts/patch-endpoint-micropub-where-note-visibility.mjs && node scripts/patch-endpoint-posts-ai-fields.mjs && node scripts/patch-endpoint-posts-ai-cleanup.mjs && node scripts/patch-endpoint-podroll-opml-upload.mjs && node scripts/patch-preset-eleventy-ai-frontmatter.mjs && node scripts/patch-micropub-ai-block-resync.mjs && node scripts/patch-frontend-serviceworker-file.mjs && node scripts/patch-endpoint-comments-locales.mjs && node scripts/patch-conversations-collection-guards.mjs && node scripts/patch-conversations-mastodon-disconnect.mjs && node scripts/patch-indiekit-routes-rate-limits.mjs && node scripts/patch-indiekit-error-production-stack.mjs && node scripts/patch-indieauth-devmode-guard.mjs && node scripts/patch-listening-endpoint-runtime-guards.mjs && node scripts/patch-endpoint-github-changelog-categories.mjs && node scripts/patch-microsub-reader-ap-dispatch.mjs && node scripts/patch-endpoint-blogroll-feeds-alias.mjs && node scripts/patch-endpoint-posts-uid-lookup.mjs && node scripts/patch-endpoint-posts-prefill-url.mjs && node scripts/patch-microsub-feed-discovery.mjs && node scripts/patch-conversations-bluesky-self-filter.mjs && node scripts/patch-conversations-bluesky-cursor-fix.mjs && node scripts/patch-inbox-ignore-view-activity.mjs && node scripts/patch-inbox-skip-view-activity-parse.mjs", - "serve":"export NODE_ENV=${NODE_ENV:-production} INDIEKIT_DEBUG=${INDIEKIT_DEBUG:-0} && node scripts/preflight-production-security.mjs && node scripts/preflight-mongo-connection.mjs && node scripts/preflight-activitypub-rsa-key.mjs && node scripts/preflight-activitypub-profile-urls.mjs && node scripts/patch-lightningcss.mjs && node scripts/patch-endpoint-media-scope.mjs && node scripts/patch-endpoint-media-sharp-runtime.mjs && node scripts/patch-frontend-sharp-runtime.mjs && node scripts/patch-endpoint-files-upload-route.mjs && node scripts/patch-endpoint-files-upload-locales.mjs && node scripts/patch-endpoint-activitypub-locales.mjs && node scripts/patch-endpoint-homepage-locales.mjs && node scripts/patch-endpoint-homepage-identity-defaults.mjs && node scripts/patch-federation-unlisted-guards.mjs && node scripts/patch-endpoint-micropub-where-note-visibility.mjs && node scripts/patch-endpoint-posts-ai-fields.mjs && node scripts/patch-endpoint-posts-ai-cleanup.mjs && node scripts/patch-endpoint-podroll-opml-upload.mjs && node scripts/patch-preset-eleventy-ai-frontmatter.mjs && node scripts/patch-micropub-ai-block-resync.mjs && node scripts/patch-frontend-serviceworker-file.mjs && node scripts/patch-endpoint-comments-locales.mjs && node scripts/patch-conversations-collection-guards.mjs && node scripts/patch-conversations-mastodon-disconnect.mjs && node scripts/patch-indiekit-routes-rate-limits.mjs && node scripts/patch-indiekit-error-production-stack.mjs && node scripts/patch-indieauth-devmode-guard.mjs && node scripts/patch-listening-endpoint-runtime-guards.mjs && node scripts/patch-endpoint-github-changelog-categories.mjs && node scripts/patch-microsub-reader-ap-dispatch.mjs && node scripts/patch-endpoint-blogroll-feeds-alias.mjs && node scripts/patch-endpoint-posts-uid-lookup.mjs && node scripts/patch-endpoint-posts-prefill-url.mjs && node scripts/patch-microsub-feed-discovery.mjs && node scripts/patch-conversations-bluesky-self-filter.mjs && node scripts/patch-conversations-bluesky-cursor-fix.mjs && node node_modules/@indiekit/indiekit/bin/cli.js serve --config indiekit.config.mjs", + "postinstall": "xattr -w com.apple.fileprovider.ignore#P 1 node_modules 2>/dev/null || true && node scripts/patch-lightningcss.mjs && node scripts/patch-endpoint-media-scope.mjs && node scripts/patch-endpoint-media-sharp-runtime.mjs && node scripts/patch-frontend-sharp-runtime.mjs && node scripts/patch-endpoint-files-upload-route.mjs && node scripts/patch-endpoint-files-upload-locales.mjs && node scripts/patch-endpoint-activitypub-locales.mjs && node scripts/patch-endpoint-homepage-locales.mjs && node scripts/patch-endpoint-homepage-identity-defaults.mjs && node scripts/patch-federation-unlisted-guards.mjs && node scripts/patch-endpoint-micropub-where-note-visibility.mjs && node scripts/patch-endpoint-posts-ai-fields.mjs && node scripts/patch-endpoint-posts-ai-cleanup.mjs && node scripts/patch-endpoint-podroll-opml-upload.mjs && node scripts/patch-preset-eleventy-ai-frontmatter.mjs && node scripts/patch-micropub-ai-block-resync.mjs && node scripts/patch-frontend-serviceworker-file.mjs && node scripts/patch-endpoint-comments-locales.mjs && node scripts/patch-conversations-collection-guards.mjs && node scripts/patch-indiekit-routes-rate-limits.mjs && node scripts/patch-indiekit-error-production-stack.mjs && node scripts/patch-indieauth-devmode-guard.mjs && node scripts/patch-listening-endpoint-runtime-guards.mjs && node scripts/patch-endpoint-github-changelog-categories.mjs && node scripts/patch-microsub-reader-ap-dispatch.mjs && node scripts/patch-endpoint-blogroll-feeds-alias.mjs && node scripts/patch-endpoint-posts-uid-lookup.mjs && node scripts/patch-endpoint-posts-prefill-url.mjs && node scripts/patch-microsub-feed-discovery.mjs && node scripts/patch-conversations-bluesky-self-filter.mjs && node scripts/patch-conversations-bluesky-cursor-fix.mjs && node scripts/patch-inbox-ignore-view-activity.mjs && node scripts/patch-inbox-skip-view-activity-parse.mjs", + "serve": "export NODE_ENV=${NODE_ENV:-production} INDIEKIT_DEBUG=${INDIEKIT_DEBUG:-0} && node scripts/preflight-production-security.mjs && node scripts/preflight-mongo-connection.mjs && node scripts/preflight-activitypub-rsa-key.mjs && node scripts/preflight-activitypub-profile-urls.mjs && node scripts/patch-lightningcss.mjs && node scripts/patch-endpoint-media-scope.mjs && node scripts/patch-endpoint-media-sharp-runtime.mjs && node scripts/patch-frontend-sharp-runtime.mjs && node scripts/patch-endpoint-files-upload-route.mjs && node scripts/patch-endpoint-files-upload-locales.mjs && node scripts/patch-endpoint-activitypub-locales.mjs && node scripts/patch-endpoint-homepage-locales.mjs && node scripts/patch-endpoint-homepage-identity-defaults.mjs && node scripts/patch-federation-unlisted-guards.mjs && node scripts/patch-endpoint-micropub-where-note-visibility.mjs && node scripts/patch-endpoint-posts-ai-fields.mjs && node scripts/patch-endpoint-posts-ai-cleanup.mjs && node scripts/patch-endpoint-podroll-opml-upload.mjs && node scripts/patch-preset-eleventy-ai-frontmatter.mjs && node scripts/patch-micropub-ai-block-resync.mjs && node scripts/patch-frontend-serviceworker-file.mjs && node scripts/patch-endpoint-comments-locales.mjs && node scripts/patch-conversations-collection-guards.mjs && node scripts/patch-indiekit-routes-rate-limits.mjs && node scripts/patch-indiekit-error-production-stack.mjs && node scripts/patch-indieauth-devmode-guard.mjs && node scripts/patch-listening-endpoint-runtime-guards.mjs && node scripts/patch-endpoint-github-changelog-categories.mjs && node scripts/patch-microsub-reader-ap-dispatch.mjs && node scripts/patch-endpoint-blogroll-feeds-alias.mjs && node scripts/patch-endpoint-posts-uid-lookup.mjs && node scripts/patch-endpoint-posts-prefill-url.mjs && node scripts/patch-microsub-feed-discovery.mjs && node scripts/patch-conversations-bluesky-self-filter.mjs && node scripts/patch-conversations-bluesky-cursor-fix.mjs && node node_modules/@indiekit/indiekit/bin/cli.js serve --config indiekit.config.mjs", "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], @@ -45,7 +45,6 @@ "@rmdes/indiekit-preset-eleventy": "^1.0.0-beta.33", "@rmdes/indiekit-syndicator-bluesky": "^1.0.19", "@rmdes/indiekit-syndicator-indienews": "^1.0.1", - "@rmdes/indiekit-syndicator-mastodon": "^1.0.8", "dotenv": "^17.3.1", "mongodb": "^7.1.0", "node-gyp": "^12.2.0" diff --git a/scripts/patch-conversations-mastodon-disconnect.mjs b/scripts/patch-conversations-mastodon-disconnect.mjs deleted file mode 100644 index 9353487e..00000000 --- a/scripts/patch-conversations-mastodon-disconnect.mjs +++ /dev/null @@ -1,325 +0,0 @@ -import { access, readFile, writeFile } from "node:fs/promises"; - -const conversationsIndexCandidates = [ - "node_modules/@rmdes/indiekit-endpoint-conversations/index.js", - "node_modules/@indiekit/indiekit/node_modules/@rmdes/indiekit-endpoint-conversations/index.js", -]; - -const conversationsControllerCandidates = [ - "node_modules/@rmdes/indiekit-endpoint-conversations/lib/controllers/conversations.js", - "node_modules/@indiekit/indiekit/node_modules/@rmdes/indiekit-endpoint-conversations/lib/controllers/conversations.js", -]; - -const conversationsSchedulerCandidates = [ - "node_modules/@rmdes/indiekit-endpoint-conversations/lib/polling/scheduler.js", - "node_modules/@indiekit/indiekit/node_modules/@rmdes/indiekit-endpoint-conversations/lib/polling/scheduler.js", -]; - -const conversationsViewCandidates = [ - "node_modules/@rmdes/indiekit-endpoint-conversations/views/conversations.njk", - "node_modules/@indiekit/indiekit/node_modules/@rmdes/indiekit-endpoint-conversations/views/conversations.njk", -]; - -const patchSpecs = [ - { - name: "conversations-index-mastodon-disconnect-routes", - candidates: conversationsIndexCandidates, - oldSnippet: ` // Manual poll trigger (admin only) - router.post("/poll", conversationsController.triggerPoll); - - return router;`, - newSnippet: ` // Manual poll trigger (admin only) - router.post("/poll", conversationsController.triggerPoll); - router.post("/mastodon/logout", conversationsController.logoutMastodon); - router.post("/mastodon/reconnect", conversationsController.reconnectMastodon); - - return router;`, - }, - { - name: "conversations-dashboard-connection-state", - candidates: conversationsControllerCandidates, - marker: "const connectionState = {", - oldSnippet: ` // Get stats - const totalItems = await getConversationCount(application);`, - newSnippet: ` const connectionState = { - mastodonEnabled: - !!config.mastodonEnabled && !pollState?.mastodon_disabled, - blueskyEnabled: !!config.blueskyEnabled, - activitypubEnabled: !!config.activitypubEnabled, - }; - - // Get stats - const totalItems = await getConversationCount(application);`, - }, - { - name: "conversations-dashboard-render-connection-state", - candidates: conversationsControllerCandidates, - oldSnippet: ` config, - pollState, - totalItems,`, - newSnippet: ` config, - pollState, - connectionState, - totalItems,`, - }, - { - name: "conversations-dashboard-error-render-connection-state", - candidates: conversationsControllerCandidates, - oldSnippet: ` config: {}, - totalItems: 0,`, - newSnippet: ` config: {}, - connectionState: { - mastodonEnabled: false, - blueskyEnabled: false, - activitypubEnabled: false, - }, - totalItems: 0,`, - }, - { - name: "conversations-status-mastodon-disabled-flag", - candidates: conversationsControllerCandidates, - oldSnippet: ` const totalItems = await getConversationCount(application); - - response.json({ - status: "ok", - mastodon: { - enabled: !!config.mastodonEnabled,`, - newSnippet: ` const totalItems = await getConversationCount(application); - const mastodonEnabled = - !!config.mastodonEnabled && !pollState?.mastodon_disabled; - - response.json({ - status: "ok", - mastodon: { - enabled: mastodonEnabled, - disabledByAdmin: !!pollState?.mastodon_disabled,`, - }, - { - name: "conversations-controller-mastodon-disconnect-handlers", - candidates: conversationsControllerCandidates, - marker: "async function logoutMastodon(request, response)", - oldSnippet: `/** - * Ingest a webmention`, - newSnippet: `/** - * Disable Mastodon polling (dashboard logout/disconnect action) - * POST /conversations/mastodon/logout - */ -async function logoutMastodon(request, response) { - const { application } = request.app.locals; - const config = application?.conversations || {}; - const stateCollection = application?.collections?.get("conversation_state"); - - try { - if (stateCollection) { - await stateCollection.findOneAndUpdate( - { _id: "poll_cursors" }, - { - $set: { - mastodon_disabled: true, - mastodon_last_error: null, - mastodon_last_poll: new Date().toISOString(), - mastodon_last_disabled_at: new Date().toISOString(), - }, - $unset: { - mastodon_since_id: "", - }, - }, - { upsert: true }, - ); - } - - response.redirect((config.mountPath || "/conversations") + "?mastodon=logged_out"); - } catch (error) { - console.error("[Conversations] Mastodon logout error:", error.message); - response.redirect( - (config.mountPath || "/conversations") + "?error=mastodon_logout_failed", - ); - } -} - -/** - * Re-enable Mastodon polling after dashboard disconnect - * POST /conversations/mastodon/reconnect - */ -async function reconnectMastodon(request, response) { - const { application } = request.app.locals; - const config = application?.conversations || {}; - const stateCollection = application?.collections?.get("conversation_state"); - - try { - if (stateCollection) { - await stateCollection.findOneAndUpdate( - { _id: "poll_cursors" }, - { - $unset: { - mastodon_disabled: "", - }, - $set: { - mastodon_last_error: null, - mastodon_last_poll: new Date().toISOString(), - }, - }, - { upsert: true }, - ); - } - - response.redirect((config.mountPath || "/conversations") + "?mastodon=reconnected"); - } catch (error) { - console.error("[Conversations] Mastodon reconnect error:", error.message); - response.redirect( - (config.mountPath || "/conversations") + "?error=mastodon_reconnect_failed", - ); - } -} - -/** - * Ingest a webmention`, - }, - { - name: "conversations-controller-export-disconnect-handlers", - candidates: conversationsControllerCandidates, - oldSnippet: ` triggerPoll, - ingest,`, - newSnippet: ` triggerPoll, - logoutMastodon, - reconnectMastodon, - ingest,`, - }, - { - name: "conversations-scheduler-mastodon-disabled-check", - candidates: conversationsSchedulerCandidates, - oldSnippet: ` const mastodonToken = process.env.MASTODON_ACCESS_TOKEN; - const hasMastodon = mastodonUrl && mastodonToken;`, - newSnippet: ` const mastodonToken = process.env.MASTODON_ACCESS_TOKEN; - const mastodonDisabled = state.mastodon_disabled === true; - const hasMastodon = !mastodonDisabled && mastodonUrl && mastodonToken;`, - }, - { - name: "conversations-scheduler-mastodon-403-backoff", - candidates: conversationsSchedulerCandidates, - oldSnippet: ` if (error.status === 429 || error.status === 401) {`, - newSnippet: ` if (error.status === 429 || error.status === 401 || error.status === 403) {`, - }, - { - name: "conversations-view-mastodon-connection-state", - candidates: conversationsViewCandidates, - oldSnippet: "config.mastodonEnabled", - newSnippet: "connectionState.mastodonEnabled", - replaceAll: true, - }, - { - name: "conversations-view-bluesky-connection-state", - candidates: conversationsViewCandidates, - oldSnippet: "config.blueskyEnabled", - newSnippet: "connectionState.blueskyEnabled", - replaceAll: true, - }, - { - name: "conversations-view-activitypub-connection-state", - candidates: conversationsViewCandidates, - oldSnippet: "config.activitypubEnabled", - newSnippet: "connectionState.activitypubEnabled", - replaceAll: true, - }, - { - name: "conversations-view-mastodon-logout-button", - candidates: conversationsViewCandidates, - marker: "action=\"{{ baseUrl }}/mastodon/logout\"", - oldSnippet: `

- {{ platformCounts.mastodon or 0 }} {{ __("conversations.dashboard.itemsCollected") }} -

`, - newSnippet: `

- {{ platformCounts.mastodon or 0 }} {{ __("conversations.dashboard.itemsCollected") }} -

-
- -
`, - }, - { - name: "conversations-view-mastodon-disabled-state", - candidates: conversationsViewCandidates, - marker: "Mastodon polling is disconnected for this dashboard.", - oldSnippet: ` {% else %} -

- {{ __("conversations.dashboard.mastodonHint") }} -

- {% endif %}`, - newSnippet: ` {% else %} - {% if pollState and pollState.mastodon_disabled %} -

- Mastodon polling is disconnected for this dashboard. -

-
- -
- {% else %} -

- {{ __("conversations.dashboard.mastodonHint") }} -

- {% endif %} - {% endif %}`, - }, -]; - -async function exists(filePath) { - try { - await access(filePath); - return true; - } catch { - return false; - } -} - -const checkedFiles = new Set(); -const patchedFiles = new Set(); - -for (const spec of patchSpecs) { - let foundAnyTarget = false; - - for (const filePath of spec.candidates) { - if (!(await exists(filePath))) { - continue; - } - - foundAnyTarget = true; - checkedFiles.add(filePath); - - const source = await readFile(filePath, "utf8"); - - if (spec.marker && source.includes(spec.marker)) { - continue; - } - - if (!source.includes(spec.oldSnippet)) { - continue; - } - - let updated; - if (spec.replaceAll) { - updated = source.split(spec.oldSnippet).join(spec.newSnippet); - } else { - updated = source.replace(spec.oldSnippet, spec.newSnippet); - } - - if (updated === source) { - continue; - } - - await writeFile(filePath, updated, "utf8"); - patchedFiles.add(filePath); - } - - if (!foundAnyTarget) { - console.log(`[postinstall] ${spec.name}: no target files found`); - } -} - -if (checkedFiles.size === 0) { - console.log("[postinstall] No conversations mastodon disconnect files found"); -} else if (patchedFiles.size === 0) { - console.log("[postinstall] conversations mastodon disconnect patches already applied"); -} else { - console.log( - `[postinstall] Patched conversations mastodon disconnect in ${patchedFiles.size}/${checkedFiles.size} file(s)`, - ); -}