diff --git a/Cargo.lock b/Cargo.lock index 72bdab6a7..18b6b3082 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1108,18 +1108,6 @@ dependencies = [ "yaml-rust", ] -[[package]] -name = "console-api" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2895653b4d9f1538a83970077cb01dfc77a4810524e51a110944688e916b18e" -dependencies = [ - "prost 0.11.9", - "prost-types 0.11.9", - "tonic 0.9.2", - "tracing-core", -] - [[package]] name = "console-api" version = "0.6.0" @@ -1128,48 +1116,24 @@ checksum = "fd326812b3fd01da5bb1af7d340d0d555fd3d4b641e7f1dfcf5962a902952787" dependencies = [ "futures-core", "prost 0.12.6", - "prost-types 0.12.6", + "prost-types", "tonic 0.10.2", "tracing-core", ] -[[package]] -name = "console-subscriber" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4cf42660ac07fcebed809cfe561dd8730bcd35b075215e6479c516bcd0d11cb" -dependencies = [ - "console-api 0.5.0", - "crossbeam-channel", - "crossbeam-utils", - "futures", - "hdrhistogram", - "humantime", - "prost-types 0.11.9", - "serde", - "serde_json", - "thread_local", - "tokio", - "tokio-stream", - "tonic 0.9.2", - "tracing", - "tracing-core", - "tracing-subscriber", -] - [[package]] name = "console-subscriber" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7481d4c57092cd1c19dd541b92bdce883de840df30aa5d03fd48a3935c01842e" dependencies = [ - "console-api 0.6.0", + "console-api", "crossbeam-channel", "crossbeam-utils", "futures-task", "hdrhistogram", "humantime", - "prost-types 0.12.6", + "prost-types", "serde", "serde_json", "thread_local", @@ -2735,7 +2699,7 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" [[package]] name = "lemmy_api" -version = "0.19.4-rc.4" +version = "0.19.4-rc.5" dependencies = [ "activitypub_federation", "actix-web", @@ -2764,7 +2728,7 @@ dependencies = [ [[package]] name = "lemmy_api_common" -version = "0.19.4-rc.4" +version = "0.19.4-rc.5" dependencies = [ "activitypub_federation", "actix-web", @@ -2802,7 +2766,7 @@ dependencies = [ [[package]] name = "lemmy_api_crud" -version = "0.19.4-rc.4" +version = "0.19.4-rc.5" dependencies = [ "accept-language", "activitypub_federation", @@ -2825,7 +2789,7 @@ dependencies = [ [[package]] name = "lemmy_apub" -version = "0.19.4-rc.4" +version = "0.19.4-rc.5" dependencies = [ "activitypub_federation", "actix-web", @@ -2863,7 +2827,7 @@ dependencies = [ [[package]] name = "lemmy_db_perf" -version = "0.19.4-rc.4" +version = "0.19.4-rc.5" dependencies = [ "anyhow", "clap", @@ -2878,7 +2842,7 @@ dependencies = [ [[package]] name = "lemmy_db_schema" -version = "0.19.4-rc.4" +version = "0.19.4-rc.5" dependencies = [ "activitypub_federation", "anyhow", @@ -2918,7 +2882,7 @@ dependencies = [ [[package]] name = "lemmy_db_views" -version = "0.19.4-rc.4" +version = "0.19.4-rc.5" dependencies = [ "actix-web", "chrono", @@ -2940,7 +2904,7 @@ dependencies = [ [[package]] name = "lemmy_db_views_actor" -version = "0.19.4-rc.4" +version = "0.19.4-rc.5" dependencies = [ "chrono", "diesel", @@ -2961,7 +2925,7 @@ dependencies = [ [[package]] name = "lemmy_db_views_moderator" -version = "0.19.4-rc.4" +version = "0.19.4-rc.5" dependencies = [ "diesel", "diesel-async", @@ -2973,7 +2937,7 @@ dependencies = [ [[package]] name = "lemmy_federate" -version = "0.19.4-rc.4" +version = "0.19.4-rc.5" dependencies = [ "activitypub_federation", "anyhow", @@ -2998,7 +2962,7 @@ dependencies = [ [[package]] name = "lemmy_routes" -version = "0.19.4-rc.4" +version = "0.19.4-rc.5" dependencies = [ "activitypub_federation", "actix-web", @@ -3023,7 +2987,7 @@ dependencies = [ [[package]] name = "lemmy_server" -version = "0.19.4-rc.4" +version = "0.19.4-rc.5" dependencies = [ "activitypub_federation", "actix-cors", @@ -3032,7 +2996,7 @@ dependencies = [ "chrono", "clap", "clokwerk", - "console-subscriber 0.1.10", + "console-subscriber", "diesel", "diesel-async", "futures-util", @@ -3066,7 +3030,7 @@ dependencies = [ [[package]] name = "lemmy_utils" -version = "0.19.4-rc.4" +version = "0.19.4-rc.5" dependencies = [ "actix-web", "anyhow", @@ -4028,7 +3992,7 @@ dependencies = [ "clap", "color-eyre", "config", - "console-subscriber 0.2.0", + "console-subscriber", "dashmap", "diesel", "diesel-async", @@ -4337,15 +4301,6 @@ dependencies = [ "syn 2.0.65", ] -[[package]] -name = "prost-types" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" -dependencies = [ - "prost 0.11.9", -] - [[package]] name = "prost-types" version = "0.12.6" @@ -5057,9 +5012,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.202" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" dependencies = [ "serde_derive", ] @@ -5075,9 +5030,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.202" +version = "1.0.203" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" dependencies = [ "proc-macro2", "quote", @@ -5922,34 +5877,6 @@ dependencies = [ "tracing-futures", ] -[[package]] -name = "tonic" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" -dependencies = [ - "async-trait", - "axum", - "base64 0.21.7", - "bytes", - "futures-core", - "futures-util", - "h2 0.3.26", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.28", - "hyper-timeout", - "percent-encoding", - "pin-project", - "prost 0.11.9", - "tokio", - "tokio-stream", - "tower", - "tower-layer", - "tower-service", - "tracing", -] - [[package]] name = "tonic" version = "0.10.2" diff --git a/Cargo.toml b/Cargo.toml index 16940d3ff..60babeb1d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [workspace.package] -version = "0.19.4-rc.4" +version = "0.19.4-rc.5" edition = "2021" description = "A link aggregator for the fediverse" license = "AGPL-3.0" @@ -88,17 +88,17 @@ unused_self = "deny" unwrap_used = "deny" [workspace.dependencies] -lemmy_api = { version = "=0.19.4-rc.4", path = "./crates/api" } -lemmy_api_crud = { version = "=0.19.4-rc.4", path = "./crates/api_crud" } -lemmy_apub = { version = "=0.19.4-rc.4", path = "./crates/apub" } -lemmy_utils = { version = "=0.19.4-rc.4", path = "./crates/utils", default-features = false } -lemmy_db_schema = { version = "=0.19.4-rc.4", path = "./crates/db_schema" } -lemmy_api_common = { version = "=0.19.4-rc.4", path = "./crates/api_common" } -lemmy_routes = { version = "=0.19.4-rc.4", path = "./crates/routes" } -lemmy_db_views = { version = "=0.19.4-rc.4", path = "./crates/db_views" } -lemmy_db_views_actor = { version = "=0.19.4-rc.4", path = "./crates/db_views_actor" } -lemmy_db_views_moderator = { version = "=0.19.4-rc.4", path = "./crates/db_views_moderator" } -lemmy_federate = { version = "=0.19.4-rc.4", path = "./crates/federate" } +lemmy_api = { version = "=0.19.4-rc.5", path = "./crates/api" } +lemmy_api_crud = { version = "=0.19.4-rc.5", path = "./crates/api_crud" } +lemmy_apub = { version = "=0.19.4-rc.5", path = "./crates/apub" } +lemmy_utils = { version = "=0.19.4-rc.5", path = "./crates/utils", default-features = false } +lemmy_db_schema = { version = "=0.19.4-rc.5", path = "./crates/db_schema" } +lemmy_api_common = { version = "=0.19.4-rc.5", path = "./crates/api_common" } +lemmy_routes = { version = "=0.19.4-rc.5", path = "./crates/routes" } +lemmy_db_views = { version = "=0.19.4-rc.5", path = "./crates/db_views" } +lemmy_db_views_actor = { version = "=0.19.4-rc.5", path = "./crates/db_views_actor" } +lemmy_db_views_moderator = { version = "=0.19.4-rc.5", path = "./crates/db_views_moderator" } +lemmy_federate = { version = "=0.19.4-rc.5", path = "./crates/federate" } activitypub_federation = { version = "0.5.6", default-features = false, features = [ "actix-web", ] } @@ -194,7 +194,7 @@ clokwerk = { workspace = true } serde_json = { workspace = true } tracing-opentelemetry = { workspace = true, optional = true } opentelemetry = { workspace = true, optional = true } -console-subscriber = { version = "0.1.10", optional = true } +console-subscriber = { version = "0.2.0", optional = true } opentelemetry-otlp = { version = "0.12.0", optional = true } pict-rs = { version = "0.5.14", optional = true } tokio.workspace = true diff --git a/api_tests/package.json b/api_tests/package.json index b194dae30..31fbe2161 100644 --- a/api_tests/package.json +++ b/api_tests/package.json @@ -6,7 +6,7 @@ "repository": "https://github.com/LemmyNet/lemmy", "author": "Dessalines", "license": "AGPL-3.0", - "packageManager": "pnpm@9.1.1+sha256.9551e803dcb7a1839fdf5416153a844060c7bce013218ce823410532504ac10b", + "packageManager": "pnpm@9.1.4", "scripts": { "lint": "tsc --noEmit && eslint --report-unused-disable-directives --ext .js,.ts,.tsx src && prettier --check 'src/**/*.ts'", "fix": "prettier --write src && eslint --fix src", diff --git a/api_tests/pnpm-lock.yaml b/api_tests/pnpm-lock.yaml index 42eb612e5..a10c03298 100644 --- a/api_tests/pnpm-lock.yaml +++ b/api_tests/pnpm-lock.yaml @@ -16,10 +16,10 @@ importers: version: 20.12.4 '@typescript-eslint/eslint-plugin': specifier: ^7.5.0 - version: 7.5.0(@typescript-eslint/parser@7.5.0)(eslint@8.57.0)(typescript@5.4.4) + version: 7.5.0(@typescript-eslint/parser@7.5.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5) '@typescript-eslint/parser': specifier: ^7.5.0 - version: 7.5.0(eslint@8.57.0)(typescript@5.4.4) + version: 7.5.0(eslint@8.57.0)(typescript@5.4.5) download-file-sync: specifier: ^1.0.4 version: 1.0.4 @@ -40,10 +40,10 @@ importers: version: 3.2.5 ts-jest: specifier: ^29.1.0 - version: 29.1.2(@babel/core@7.23.9)(jest@29.7.0)(typescript@5.4.4) + version: 29.1.4(@babel/core@7.23.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(jest@29.7.0(@types/node@20.12.4))(typescript@5.4.5) typescript: specifier: ^5.4.4 - version: 5.4.4 + version: 5.4.5 packages: @@ -865,6 +865,7 @@ packages: glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported globals@11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} @@ -922,6 +923,7 @@ packages: inflight@1.0.6: resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -1380,6 +1382,7 @@ packages: rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported hasBin: true run-parallel@1.2.0: @@ -1389,13 +1392,13 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.5.4: - resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + semver@7.6.0: + resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} engines: {node: '>=10'} hasBin: true - semver@7.6.0: - resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==} + semver@7.6.2: + resolution: {integrity: sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==} engines: {node: '>=10'} hasBin: true @@ -1499,12 +1502,13 @@ packages: peerDependencies: typescript: '>=4.2.0' - ts-jest@29.1.2: - resolution: {integrity: sha512-br6GJoH/WUX4pu7FbZXuWGKGNDuU7b8Uj77g/Sp7puZV6EXzuByl6JrECvm0MzVzSTkSHWTihsXt+5XYER5b+g==} - engines: {node: ^16.10.0 || ^18.0.0 || >=20.0.0} + ts-jest@29.1.4: + resolution: {integrity: sha512-YiHwDhSvCiItoAgsKtoLFCuakDzDsJ1DLDnSouTaTmdOcOwIkSzbLXduaQ6M5DRVhuZC/NYaaZ/mtHbWMv/S6Q==} + engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@babel/core': '>=7.0.0-beta.0 <8' + '@jest/transform': ^29.0.0 '@jest/types': ^29.0.0 babel-jest: ^29.0.0 esbuild: '*' @@ -1513,6 +1517,8 @@ packages: peerDependenciesMeta: '@babel/core': optional: true + '@jest/transform': + optional: true '@jest/types': optional: true babel-jest: @@ -1539,8 +1545,8 @@ packages: resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} engines: {node: '>=10'} - typescript@5.4.4: - resolution: {integrity: sha512-dGE2Vv8cpVvw28v8HCPqyb08EzbBURxDpuhJvTrusShUfGnhHBafDsLdS1EhhxyL6BJQE+2cT3dDPAv+MQ6oLw==} + typescript@5.4.5: + resolution: {integrity: sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==} engines: {node: '>=14.17'} hasBin: true @@ -2113,13 +2119,13 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@7.5.0(@typescript-eslint/parser@7.5.0)(eslint@8.57.0)(typescript@5.4.4)': + '@typescript-eslint/eslint-plugin@7.5.0(@typescript-eslint/parser@7.5.0(eslint@8.57.0)(typescript@5.4.5))(eslint@8.57.0)(typescript@5.4.5)': dependencies: '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 7.5.0(eslint@8.57.0)(typescript@5.4.4) + '@typescript-eslint/parser': 7.5.0(eslint@8.57.0)(typescript@5.4.5) '@typescript-eslint/scope-manager': 7.5.0 - '@typescript-eslint/type-utils': 7.5.0(eslint@8.57.0)(typescript@5.4.4) - '@typescript-eslint/utils': 7.5.0(eslint@8.57.0)(typescript@5.4.4) + '@typescript-eslint/type-utils': 7.5.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/utils': 7.5.0(eslint@8.57.0)(typescript@5.4.5) '@typescript-eslint/visitor-keys': 7.5.0 debug: 4.3.4 eslint: 8.57.0 @@ -2127,20 +2133,22 @@ snapshots: ignore: 5.3.1 natural-compare: 1.4.0 semver: 7.6.0 - ts-api-utils: 1.3.0(typescript@5.4.4) - typescript: 5.4.4 + ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@7.5.0(eslint@8.57.0)(typescript@5.4.4)': + '@typescript-eslint/parser@7.5.0(eslint@8.57.0)(typescript@5.4.5)': dependencies: '@typescript-eslint/scope-manager': 7.5.0 '@typescript-eslint/types': 7.5.0 - '@typescript-eslint/typescript-estree': 7.5.0(typescript@5.4.4) + '@typescript-eslint/typescript-estree': 7.5.0(typescript@5.4.5) '@typescript-eslint/visitor-keys': 7.5.0 debug: 4.3.4 eslint: 8.57.0 - typescript: 5.4.4 + optionalDependencies: + typescript: 5.4.5 transitivePeerDependencies: - supports-color @@ -2149,20 +2157,21 @@ snapshots: '@typescript-eslint/types': 7.5.0 '@typescript-eslint/visitor-keys': 7.5.0 - '@typescript-eslint/type-utils@7.5.0(eslint@8.57.0)(typescript@5.4.4)': + '@typescript-eslint/type-utils@7.5.0(eslint@8.57.0)(typescript@5.4.5)': dependencies: - '@typescript-eslint/typescript-estree': 7.5.0(typescript@5.4.4) - '@typescript-eslint/utils': 7.5.0(eslint@8.57.0)(typescript@5.4.4) + '@typescript-eslint/typescript-estree': 7.5.0(typescript@5.4.5) + '@typescript-eslint/utils': 7.5.0(eslint@8.57.0)(typescript@5.4.5) debug: 4.3.4 eslint: 8.57.0 - ts-api-utils: 1.3.0(typescript@5.4.4) - typescript: 5.4.4 + ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 transitivePeerDependencies: - supports-color '@typescript-eslint/types@7.5.0': {} - '@typescript-eslint/typescript-estree@7.5.0(typescript@5.4.4)': + '@typescript-eslint/typescript-estree@7.5.0(typescript@5.4.5)': dependencies: '@typescript-eslint/types': 7.5.0 '@typescript-eslint/visitor-keys': 7.5.0 @@ -2170,20 +2179,21 @@ snapshots: globby: 11.1.0 is-glob: 4.0.3 minimatch: 9.0.3 - semver: 7.6.0 - ts-api-utils: 1.3.0(typescript@5.4.4) - typescript: 5.4.4 + semver: 7.6.2 + ts-api-utils: 1.3.0(typescript@5.4.5) + optionalDependencies: + typescript: 5.4.5 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@7.5.0(eslint@8.57.0)(typescript@5.4.4)': + '@typescript-eslint/utils@7.5.0(eslint@8.57.0)(typescript@5.4.5)': dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) '@types/json-schema': 7.0.15 '@types/semver': 7.5.8 '@typescript-eslint/scope-manager': 7.5.0 '@typescript-eslint/types': 7.5.0 - '@typescript-eslint/typescript-estree': 7.5.0(typescript@5.4.4) + '@typescript-eslint/typescript-estree': 7.5.0(typescript@5.4.5) eslint: 8.57.0 semver: 7.6.0 transitivePeerDependencies: @@ -2712,7 +2722,7 @@ snapshots: '@babel/parser': 7.23.9 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 - semver: 7.5.4 + semver: 7.6.2 transitivePeerDependencies: - supports-color @@ -2791,7 +2801,6 @@ snapshots: '@babel/core': 7.23.9 '@jest/test-sequencer': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 20.12.4 babel-jest: 29.7.0(@babel/core@7.23.9) chalk: 4.1.2 ci-info: 3.9.0 @@ -2811,6 +2820,8 @@ snapshots: pretty-format: 29.7.0 slash: 3.0.0 strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 20.12.4 transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -2892,7 +2903,7 @@ snapshots: jest-util: 29.7.0 jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): - dependencies: + optionalDependencies: jest-resolve: 29.7.0 jest-regex-util@29.6.3: {} @@ -2990,7 +3001,7 @@ snapshots: jest-util: 29.7.0 natural-compare: 1.4.0 pretty-format: 29.7.0 - semver: 7.5.4 + semver: 7.6.2 transitivePeerDependencies: - supports-color @@ -3104,7 +3115,7 @@ snapshots: make-dir@4.0.0: dependencies: - semver: 7.5.4 + semver: 7.6.2 make-error@1.3.6: {} @@ -3268,14 +3279,12 @@ snapshots: semver@6.3.1: {} - semver@7.5.4: - dependencies: - lru-cache: 6.0.0 - semver@7.6.0: dependencies: lru-cache: 6.0.0 + semver@7.6.2: {} + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 @@ -3357,13 +3366,12 @@ snapshots: dependencies: is-number: 7.0.0 - ts-api-utils@1.3.0(typescript@5.4.4): + ts-api-utils@1.3.0(typescript@5.4.5): dependencies: - typescript: 5.4.4 + typescript: 5.4.5 - ts-jest@29.1.2(@babel/core@7.23.9)(jest@29.7.0)(typescript@5.4.4): + ts-jest@29.1.4(@babel/core@7.23.9)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.23.9))(jest@29.7.0(@types/node@20.12.4))(typescript@5.4.5): dependencies: - '@babel/core': 7.23.9 bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 jest: 29.7.0(@types/node@20.12.4) @@ -3371,9 +3379,14 @@ snapshots: json5: 2.2.3 lodash.memoize: 4.1.2 make-error: 1.3.6 - semver: 7.5.4 - typescript: 5.4.4 + semver: 7.6.2 + typescript: 5.4.5 yargs-parser: 21.1.1 + optionalDependencies: + '@babel/core': 7.23.9 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.23.9) tslib@2.6.2: {} @@ -3387,7 +3400,7 @@ snapshots: type-fest@0.21.3: {} - typescript@5.4.4: {} + typescript@5.4.5: {} undici-types@5.26.5: {} diff --git a/crates/routes/src/nodeinfo.rs b/crates/routes/src/nodeinfo.rs index f64bb72c5..bcb835309 100644 --- a/crates/routes/src/nodeinfo.rs +++ b/crates/routes/src/nodeinfo.rs @@ -9,17 +9,21 @@ use lemmy_utils::{ VERSION, }; use serde::{Deserialize, Serialize}; +use std::collections::HashMap; use url::Url; +/// A description of the nodeinfo endpoint is here: +/// https://github.com/jhass/nodeinfo/blob/main/PROTOCOL.md pub fn config(cfg: &mut web::ServiceConfig) { cfg .route( - "/nodeinfo/2.1.json", + "/nodeinfo/2.1", web::get().to(node_info).wrap(cache_1hour()), ) - .service(web::redirect("/version", "/nodeinfo/2.1.json")) + .service(web::redirect("/version", "/nodeinfo/2.1")) // For backwards compatibility, can be removed after Lemmy 0.20 - .service(web::redirect("/nodeinfo/2.0.json", "/nodeinfo/2.1.json")) + .service(web::redirect("/nodeinfo/2.0.json", "/nodeinfo/2.1")) + .service(web::redirect("/nodeinfo/2.1.json", "/nodeinfo/2.1")) .route( "/.well-known/nodeinfo", web::get().to(node_info_well_known).wrap(cache_3days()), @@ -31,7 +35,7 @@ async fn node_info_well_known(context: web::Data) -> LemmyResult) -> Result, } #[derive(Serialize, Deserialize, Debug)] -struct NodeInfoWellKnownLinks { +pub struct NodeInfoWellKnownLinks { pub rel: Url, pub href: Url, } @@ -99,7 +103,7 @@ pub struct NodeInfo { pub open_registrations: Option, /// These fields are required by the spec for no reason pub services: Option, - pub metadata: Option>, + pub metadata: Option>, } #[derive(Serialize, Deserialize, Debug, Default)] diff --git a/crates/utils/translations b/crates/utils/translations index e9b3b25fa..dca5d8ca0 160000 --- a/crates/utils/translations +++ b/crates/utils/translations @@ -1 +1 @@ -Subproject commit e9b3b25fa1af7e06c4ffab86624d95da0836ef36 +Subproject commit dca5d8ca0309d7cb07eaca821140e4525e75ee57 diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 493b9c205..2a04debdd 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -75,7 +75,7 @@ services: init: true pictrs: - image: asonix/pictrs:0.5.13 + image: asonix/pictrs:0.5.14 # this needs to match the pictrs url in lemmy.hjson hostname: pictrs # we can set options to pictrs like this, here we set max. image size and forced format for conversion diff --git a/docker/federation/docker-compose.yml b/docker/federation/docker-compose.yml index ac4ef4649..ec131a2b8 100644 --- a/docker/federation/docker-compose.yml +++ b/docker/federation/docker-compose.yml @@ -49,7 +49,7 @@ services: pictrs: restart: always - image: asonix/pictrs:0.5.13 + image: asonix/pictrs:0.5.14 user: 991:991 volumes: - ./volumes/pictrs_alpha:/mnt:Z diff --git a/src/scheduled_tasks.rs b/src/scheduled_tasks.rs index e591842c6..87a2cdfb8 100644 --- a/src/scheduled_tasks.rs +++ b/src/scheduled_tasks.rs @@ -28,7 +28,7 @@ use lemmy_db_schema::{ }, utils::{get_conn, naive_now, now, DbPool, DELETED_REPLACEMENT_TEXT}, }; -use lemmy_routes::nodeinfo::NodeInfo; +use lemmy_routes::nodeinfo::{NodeInfo, NodeInfoWellKnown}; use lemmy_utils::error::LemmyResult; use reqwest_middleware::ClientWithMiddleware; use std::time::Duration; @@ -450,7 +450,10 @@ async fn update_banned_when_expired(pool: &mut DbPool<'_>) { } } -/// Updates the instance software and version +/// Updates the instance software and version. +/// +/// Does so using the /.well-known/nodeinfo protocol described here: +/// https://github.com/jhass/nodeinfo/blob/main/PROTOCOL.md /// /// TODO: if instance has been dead for a long time, it should be checked less frequently async fn update_instance_software( @@ -465,46 +468,7 @@ async fn update_instance_software( let instances = instance::table.get_results::(&mut conn).await?; for instance in instances { - let node_info_url = format!("https://{}/nodeinfo/2.0.json", instance.domain); - - // The `updated` column is used to check if instances are alive. If it is more than three - // days in the past, no outgoing activities will be sent to that instance. However - // not every Fediverse instance has a valid Nodeinfo endpoint (its not required for - // Activitypub). That's why we always need to mark instances as updated if they are - // alive. - let default_form = InstanceForm::builder() - .domain(instance.domain.clone()) - .updated(Some(naive_now())) - .build(); - let form = match client.get(&node_info_url).send().await { - Ok(res) if res.status().is_client_error() => { - // Instance doesn't have nodeinfo but sent a response, consider it alive - Some(default_form) - } - Ok(res) => match res.json::().await { - Ok(node_info) => { - // Instance sent valid nodeinfo, write it to db - let software = node_info.software.as_ref(); - Some( - InstanceForm::builder() - .domain(instance.domain) - .updated(Some(naive_now())) - .software(software.and_then(|s| s.name.clone())) - .version(software.and_then(|s| s.version.clone())) - .build(), - ) - } - Err(_) => { - // No valid nodeinfo but valid HTTP response, consider instance alive - Some(default_form) - } - }, - Err(_) => { - // dead instance, do nothing - None - } - }; - if let Some(form) = form { + if let Some(form) = build_update_instance_form(&instance.domain, client).await { Instance::update(pool, instance.id, form).await?; } } @@ -517,28 +481,114 @@ async fn update_instance_software( Ok(()) } +/// This builds an instance update form, for a given domain. +/// If the instance sends a response, but doesn't have a well-known or nodeinfo, +/// Then return a default form with only the updated field. +/// +/// TODO This function is a bit of a nightmare with its embedded matches, but the only other way +/// would be to extract the fetches into functions which return the default_form on errors. +async fn build_update_instance_form( + domain: &str, + client: &ClientWithMiddleware, +) -> Option { + // The `updated` column is used to check if instances are alive. If it is more than three + // days in the past, no outgoing activities will be sent to that instance. However + // not every Fediverse instance has a valid Nodeinfo endpoint (its not required for + // Activitypub). That's why we always need to mark instances as updated if they are + // alive. + let mut instance_form = InstanceForm::builder() + .domain(domain.to_string()) + .updated(Some(naive_now())) + .build(); + + // First, fetch their /.well-known/nodeinfo, then extract the correct nodeinfo link from it + let well_known_url = format!("https://{}/.well-known/nodeinfo", domain); + + match client.get(&well_known_url).send().await { + Ok(res) if res.status().is_client_error() => { + // Instance doesn't have well-known but sent a response, consider it alive + Some(instance_form) + } + Ok(res) => match res.json::().await { + Ok(well_known) => { + // Find the first link where the rel contains the allowed rels above + match well_known.links.into_iter().find(|links| { + links + .rel + .as_str() + .starts_with("http://nodeinfo.diaspora.software/ns/schema/2.") + }) { + Some(well_known_link) => { + let node_info_url = well_known_link.href; + + // Fetch the node_info from the well known href + match client.get(node_info_url).send().await { + Ok(node_info_res) => match node_info_res.json::().await { + Ok(node_info) => { + // Instance sent valid nodeinfo, write it to db + // Set the instance form fields. + if let Some(software) = node_info.software.as_ref() { + instance_form.software.clone_from(&software.name); + instance_form.version.clone_from(&software.version); + } + Some(instance_form) + } + Err(_) => Some(instance_form), + }, + Err(_) => Some(instance_form), + } + } + // If none is found, use the default form above + None => Some(instance_form), + } + } + Err(_) => { + // No valid nodeinfo but valid HTTP response, consider instance alive + Some(instance_form) + } + }, + Err(_) => { + // dead instance, do nothing + None + } + } +} #[cfg(test)] -#[allow(clippy::unwrap_used)] #[allow(clippy::indexing_slicing)] mod tests { - use lemmy_routes::nodeinfo::NodeInfo; + use crate::scheduled_tasks::build_update_instance_form; + use lemmy_api_common::request::client_builder; + use lemmy_utils::{error::LemmyResult, settings::structs::Settings, LemmyErrorType}; use pretty_assertions::assert_eq; - use reqwest::Client; + use reqwest_middleware::ClientBuilder; + use serial_test::serial; #[tokio::test] - #[ignore] - async fn test_nodeinfo() { - let client = Client::builder().build().unwrap(); - let lemmy_ml_nodeinfo = client - .get("https://lemmy.ml/nodeinfo/2.0.json") - .send() + #[serial] + async fn test_nodeinfo_voyager_lemmy_ml() -> LemmyResult<()> { + let client = ClientBuilder::new(client_builder(&Settings::default()).build()?).build(); + let form = build_update_instance_form("voyager.lemmy.ml", &client) .await - .unwrap() - .json::() - .await - .unwrap(); + .ok_or(LemmyErrorType::CouldntFindObject)?; + assert_eq!( + form.software.ok_or(LemmyErrorType::CouldntFindObject)?, + "lemmy" + ); + Ok(()) + } - assert_eq!(lemmy_ml_nodeinfo.software.unwrap().name.unwrap(), "lemmy"); + #[tokio::test] + #[serial] + async fn test_nodeinfo_mastodon_social() -> LemmyResult<()> { + let client = ClientBuilder::new(client_builder(&Settings::default()).build()?).build(); + let form = build_update_instance_form("mastodon.social", &client) + .await + .ok_or(LemmyErrorType::CouldntFindObject)?; + assert_eq!( + form.software.ok_or(LemmyErrorType::CouldntFindObject)?, + "mastodon" + ); + Ok(()) } }