mirror of https://github.com/LemmyNet/lemmy.git
When banning a federated user, also remove their content from our local
communities. - This works by: - Before a site ban, find all posts and comments to local communities - Send a federated community ban action for each local comm. - This also removes their content in the apub receive code. - Adding back in federated community ban api tests. - Adding in two more api tests for site bans. - Fixes #4118content_removal_remote_users
parent
f56b84615c
commit
4c6eb61c4a
|
@ -2555,6 +2555,7 @@ dependencies = [
|
|||
"captcha",
|
||||
"chrono",
|
||||
"elementtree",
|
||||
"itertools 0.12.0",
|
||||
"lemmy_api_common",
|
||||
"lemmy_db_schema",
|
||||
"lemmy_db_views",
|
||||
|
|
|
@ -19,16 +19,16 @@
|
|||
"api-test-image": "jest -i image.spec.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "^29.5.11",
|
||||
"@types/node": "^20.10.4",
|
||||
"@typescript-eslint/eslint-plugin": "^6.14.0",
|
||||
"@typescript-eslint/parser": "^6.14.0",
|
||||
"@types/jest": "^29.5.12",
|
||||
"@types/node": "^20.11.19",
|
||||
"@typescript-eslint/eslint-plugin": "^7.0.2",
|
||||
"@typescript-eslint/parser": "^7.0.2",
|
||||
"download-file-sync": "^1.0.4",
|
||||
"eslint": "^8.55.0",
|
||||
"eslint-plugin-prettier": "^5.0.1",
|
||||
"jest": "^29.5.0",
|
||||
"lemmy-js-client": "0.19.3-alpha.2",
|
||||
"prettier": "^3.1.1",
|
||||
"lemmy-js-client": "0.19.4-alpha.4",
|
||||
"prettier": "^3.2.5",
|
||||
"ts-jest": "^29.1.0",
|
||||
"typescript": "^5.3.3"
|
||||
}
|
||||
|
|
|
@ -6,17 +6,17 @@ settings:
|
|||
|
||||
devDependencies:
|
||||
'@types/jest':
|
||||
specifier: ^29.5.11
|
||||
version: 29.5.11
|
||||
specifier: ^29.5.12
|
||||
version: 29.5.12
|
||||
'@types/node':
|
||||
specifier: ^20.10.4
|
||||
version: 20.11.10
|
||||
specifier: ^20.11.19
|
||||
version: 20.11.19
|
||||
'@typescript-eslint/eslint-plugin':
|
||||
specifier: ^6.14.0
|
||||
version: 6.19.1(@typescript-eslint/parser@6.19.1)(eslint@8.56.0)(typescript@5.3.3)
|
||||
specifier: ^7.0.2
|
||||
version: 7.0.2(@typescript-eslint/parser@7.0.2)(eslint@8.56.0)(typescript@5.3.3)
|
||||
'@typescript-eslint/parser':
|
||||
specifier: ^6.14.0
|
||||
version: 6.19.1(eslint@8.56.0)(typescript@5.3.3)
|
||||
specifier: ^7.0.2
|
||||
version: 7.0.2(eslint@8.56.0)(typescript@5.3.3)
|
||||
download-file-sync:
|
||||
specifier: ^1.0.4
|
||||
version: 1.0.4
|
||||
|
@ -25,16 +25,16 @@ devDependencies:
|
|||
version: 8.56.0
|
||||
eslint-plugin-prettier:
|
||||
specifier: ^5.0.1
|
||||
version: 5.1.3(eslint@8.56.0)(prettier@3.2.4)
|
||||
version: 5.1.3(eslint@8.56.0)(prettier@3.2.5)
|
||||
jest:
|
||||
specifier: ^29.5.0
|
||||
version: 29.7.0(@types/node@20.11.10)
|
||||
version: 29.7.0(@types/node@20.11.19)
|
||||
lemmy-js-client:
|
||||
specifier: 0.19.3-alpha.2
|
||||
version: 0.19.3-alpha.2
|
||||
specifier: 0.19.4-alpha.4
|
||||
version: 0.19.4-alpha.4
|
||||
prettier:
|
||||
specifier: ^3.1.1
|
||||
version: 3.2.4
|
||||
specifier: ^3.2.5
|
||||
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.3.3)
|
||||
|
@ -464,7 +464,7 @@ packages:
|
|||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
dependencies:
|
||||
'@jest/types': 29.6.3
|
||||
'@types/node': 20.11.10
|
||||
'@types/node': 20.11.19
|
||||
chalk: 4.1.2
|
||||
jest-message-util: 29.7.0
|
||||
jest-util: 29.7.0
|
||||
|
@ -485,14 +485,14 @@ packages:
|
|||
'@jest/test-result': 29.7.0
|
||||
'@jest/transform': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
'@types/node': 20.11.10
|
||||
'@types/node': 20.11.19
|
||||
ansi-escapes: 4.3.2
|
||||
chalk: 4.1.2
|
||||
ci-info: 3.9.0
|
||||
exit: 0.1.2
|
||||
graceful-fs: 4.2.11
|
||||
jest-changed-files: 29.7.0
|
||||
jest-config: 29.7.0(@types/node@20.11.10)
|
||||
jest-config: 29.7.0(@types/node@20.11.19)
|
||||
jest-haste-map: 29.7.0
|
||||
jest-message-util: 29.7.0
|
||||
jest-regex-util: 29.6.3
|
||||
|
@ -520,7 +520,7 @@ packages:
|
|||
dependencies:
|
||||
'@jest/fake-timers': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
'@types/node': 20.11.10
|
||||
'@types/node': 20.11.19
|
||||
jest-mock: 29.7.0
|
||||
dev: true
|
||||
|
||||
|
@ -547,7 +547,7 @@ packages:
|
|||
dependencies:
|
||||
'@jest/types': 29.6.3
|
||||
'@sinonjs/fake-timers': 10.3.0
|
||||
'@types/node': 20.11.10
|
||||
'@types/node': 20.11.19
|
||||
jest-message-util: 29.7.0
|
||||
jest-mock: 29.7.0
|
||||
jest-util: 29.7.0
|
||||
|
@ -580,7 +580,7 @@ packages:
|
|||
'@jest/transform': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
'@jridgewell/trace-mapping': 0.3.22
|
||||
'@types/node': 20.11.10
|
||||
'@types/node': 20.11.19
|
||||
chalk: 4.1.2
|
||||
collect-v8-coverage: 1.0.2
|
||||
exit: 0.1.2
|
||||
|
@ -668,7 +668,7 @@ packages:
|
|||
'@jest/schemas': 29.6.3
|
||||
'@types/istanbul-lib-coverage': 2.0.6
|
||||
'@types/istanbul-reports': 3.0.4
|
||||
'@types/node': 20.11.10
|
||||
'@types/node': 20.11.19
|
||||
'@types/yargs': 17.0.32
|
||||
chalk: 4.1.2
|
||||
dev: true
|
||||
|
@ -777,7 +777,7 @@ packages:
|
|||
/@types/graceful-fs@4.1.9:
|
||||
resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==}
|
||||
dependencies:
|
||||
'@types/node': 20.11.10
|
||||
'@types/node': 20.11.19
|
||||
dev: true
|
||||
|
||||
/@types/istanbul-lib-coverage@2.0.6:
|
||||
|
@ -796,8 +796,8 @@ packages:
|
|||
'@types/istanbul-lib-report': 3.0.3
|
||||
dev: true
|
||||
|
||||
/@types/jest@29.5.11:
|
||||
resolution: {integrity: sha512-S2mHmYIVe13vrm6q4kN6fLYYAka15ALQki/vgDC3mIukEOx8WJlv0kQPM+d4w8Gp6u0uSdKND04IlTXBv0rwnQ==}
|
||||
/@types/jest@29.5.12:
|
||||
resolution: {integrity: sha512-eDC8bTvT/QhYdxJAulQikueigY5AsdBRH2yDKW3yveW7svY3+DzN84/2NUgkw10RTiJbWqZrTtoGVdYlvFJdLw==}
|
||||
dependencies:
|
||||
expect: 29.7.0
|
||||
pretty-format: 29.7.0
|
||||
|
@ -807,14 +807,14 @@ packages:
|
|||
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
|
||||
dev: true
|
||||
|
||||
/@types/node@20.11.10:
|
||||
resolution: {integrity: sha512-rZEfe/hJSGYmdfX9tvcPMYeYPW2sNl50nsw4jZmRcaG0HIAb0WYEpsB05GOb53vjqpyE9GUhlDQ4jLSoB5q9kg==}
|
||||
/@types/node@20.11.19:
|
||||
resolution: {integrity: sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==}
|
||||
dependencies:
|
||||
undici-types: 5.26.5
|
||||
dev: true
|
||||
|
||||
/@types/semver@7.5.6:
|
||||
resolution: {integrity: sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A==}
|
||||
/@types/semver@7.5.7:
|
||||
resolution: {integrity: sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg==}
|
||||
dev: true
|
||||
|
||||
/@types/stack-utils@2.0.3:
|
||||
|
@ -831,49 +831,49 @@ packages:
|
|||
'@types/yargs-parser': 21.0.3
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/eslint-plugin@6.19.1(@typescript-eslint/parser@6.19.1)(eslint@8.56.0)(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-roQScUGFruWod9CEyoV5KlCYrubC/fvG8/1zXuT0WTcxX87GnMMmnksMwSg99lo1xiKrBzw2icsJPMAw1OtKxg==}
|
||||
/@typescript-eslint/eslint-plugin@7.0.2(@typescript-eslint/parser@7.0.2)(eslint@8.56.0)(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-/XtVZJtbaphtdrWjr+CJclaCVGPtOdBpFEnvtNf/jRV0IiEemRrL0qABex/nEt8isYcnFacm3nPHYQwL+Wb7qg==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
peerDependencies:
|
||||
'@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha
|
||||
eslint: ^7.0.0 || ^8.0.0
|
||||
'@typescript-eslint/parser': ^7.0.0
|
||||
eslint: ^8.56.0
|
||||
typescript: '*'
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@eslint-community/regexpp': 4.10.0
|
||||
'@typescript-eslint/parser': 6.19.1(eslint@8.56.0)(typescript@5.3.3)
|
||||
'@typescript-eslint/scope-manager': 6.19.1
|
||||
'@typescript-eslint/type-utils': 6.19.1(eslint@8.56.0)(typescript@5.3.3)
|
||||
'@typescript-eslint/utils': 6.19.1(eslint@8.56.0)(typescript@5.3.3)
|
||||
'@typescript-eslint/visitor-keys': 6.19.1
|
||||
'@typescript-eslint/parser': 7.0.2(eslint@8.56.0)(typescript@5.3.3)
|
||||
'@typescript-eslint/scope-manager': 7.0.2
|
||||
'@typescript-eslint/type-utils': 7.0.2(eslint@8.56.0)(typescript@5.3.3)
|
||||
'@typescript-eslint/utils': 7.0.2(eslint@8.56.0)(typescript@5.3.3)
|
||||
'@typescript-eslint/visitor-keys': 7.0.2
|
||||
debug: 4.3.4
|
||||
eslint: 8.56.0
|
||||
graphemer: 1.4.0
|
||||
ignore: 5.3.0
|
||||
ignore: 5.3.1
|
||||
natural-compare: 1.4.0
|
||||
semver: 7.5.4
|
||||
ts-api-utils: 1.0.3(typescript@5.3.3)
|
||||
semver: 7.6.0
|
||||
ts-api-utils: 1.2.1(typescript@5.3.3)
|
||||
typescript: 5.3.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/parser@6.19.1(eslint@8.56.0)(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-WEfX22ziAh6pRE9jnbkkLGp/4RhTpffr2ZK5bJ18M8mIfA8A+k97U9ZyaXCEJRlmMHh7R9MJZWXp/r73DzINVQ==}
|
||||
/@typescript-eslint/parser@7.0.2(eslint@8.56.0)(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-GdwfDglCxSmU+QTS9vhz2Sop46ebNCXpPPvsByK7hu0rFGRHL+AusKQJ7SoN+LbLh6APFpQwHKmDSwN35Z700Q==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
peerDependencies:
|
||||
eslint: ^7.0.0 || ^8.0.0
|
||||
eslint: ^8.56.0
|
||||
typescript: '*'
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@typescript-eslint/scope-manager': 6.19.1
|
||||
'@typescript-eslint/types': 6.19.1
|
||||
'@typescript-eslint/typescript-estree': 6.19.1(typescript@5.3.3)
|
||||
'@typescript-eslint/visitor-keys': 6.19.1
|
||||
'@typescript-eslint/scope-manager': 7.0.2
|
||||
'@typescript-eslint/types': 7.0.2
|
||||
'@typescript-eslint/typescript-estree': 7.0.2(typescript@5.3.3)
|
||||
'@typescript-eslint/visitor-keys': 7.0.2
|
||||
debug: 4.3.4
|
||||
eslint: 8.56.0
|
||||
typescript: 5.3.3
|
||||
|
@ -881,41 +881,41 @@ packages:
|
|||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/scope-manager@6.19.1:
|
||||
resolution: {integrity: sha512-4CdXYjKf6/6aKNMSly/BP4iCSOpvMmqtDzRtqFyyAae3z5kkqEjKndR5vDHL8rSuMIIWP8u4Mw4VxLyxZW6D5w==}
|
||||
/@typescript-eslint/scope-manager@7.0.2:
|
||||
resolution: {integrity: sha512-l6sa2jF3h+qgN2qUMjVR3uCNGjWw4ahGfzIYsCtFrQJCjhbrDPdiihYT8FnnqFwsWX+20hK592yX9I2rxKTP4g==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 6.19.1
|
||||
'@typescript-eslint/visitor-keys': 6.19.1
|
||||
'@typescript-eslint/types': 7.0.2
|
||||
'@typescript-eslint/visitor-keys': 7.0.2
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/type-utils@6.19.1(eslint@8.56.0)(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-0vdyld3ecfxJuddDjACUvlAeYNrHP/pDeQk2pWBR2ESeEzQhg52DF53AbI9QCBkYE23lgkhLCZNkHn2hEXXYIg==}
|
||||
/@typescript-eslint/type-utils@7.0.2(eslint@8.56.0)(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-IKKDcFsKAYlk8Rs4wiFfEwJTQlHcdn8CLwLaxwd6zb8HNiMcQIFX9sWax2k4Cjj7l7mGS5N1zl7RCHOVwHq2VQ==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
peerDependencies:
|
||||
eslint: ^7.0.0 || ^8.0.0
|
||||
eslint: ^8.56.0
|
||||
typescript: '*'
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@typescript-eslint/typescript-estree': 6.19.1(typescript@5.3.3)
|
||||
'@typescript-eslint/utils': 6.19.1(eslint@8.56.0)(typescript@5.3.3)
|
||||
'@typescript-eslint/typescript-estree': 7.0.2(typescript@5.3.3)
|
||||
'@typescript-eslint/utils': 7.0.2(eslint@8.56.0)(typescript@5.3.3)
|
||||
debug: 4.3.4
|
||||
eslint: 8.56.0
|
||||
ts-api-utils: 1.0.3(typescript@5.3.3)
|
||||
ts-api-utils: 1.2.1(typescript@5.3.3)
|
||||
typescript: 5.3.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/types@6.19.1:
|
||||
resolution: {integrity: sha512-6+bk6FEtBhvfYvpHsDgAL3uo4BfvnTnoge5LrrCj2eJN8g3IJdLTD4B/jK3Q6vo4Ql/Hoip9I8aB6fF+6RfDqg==}
|
||||
/@typescript-eslint/types@7.0.2:
|
||||
resolution: {integrity: sha512-ZzcCQHj4JaXFjdOql6adYV4B/oFOFjPOC9XYwCaZFRvqN8Llfvv4gSxrkQkd2u4Ci62i2c6W6gkDwQJDaRc4nA==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/typescript-estree@6.19.1(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-aFdAxuhzBFRWhy+H20nYu19+Km+gFfwNO4TEqyszkMcgBDYQjmPJ61erHxuT2ESJXhlhrO7I5EFIlZ+qGR8oVA==}
|
||||
/@typescript-eslint/typescript-estree@7.0.2(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-3AMc8khTcELFWcKcPc0xiLviEvvfzATpdPj/DXuOGIdQIIFybf4DMT1vKRbuAEOFMwhWt7NFLXRkbjsvKZQyvw==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
peerDependencies:
|
||||
typescript: '*'
|
||||
|
@ -923,43 +923,43 @@ packages:
|
|||
typescript:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 6.19.1
|
||||
'@typescript-eslint/visitor-keys': 6.19.1
|
||||
'@typescript-eslint/types': 7.0.2
|
||||
'@typescript-eslint/visitor-keys': 7.0.2
|
||||
debug: 4.3.4
|
||||
globby: 11.1.0
|
||||
is-glob: 4.0.3
|
||||
minimatch: 9.0.3
|
||||
semver: 7.5.4
|
||||
ts-api-utils: 1.0.3(typescript@5.3.3)
|
||||
semver: 7.6.0
|
||||
ts-api-utils: 1.2.1(typescript@5.3.3)
|
||||
typescript: 5.3.3
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/utils@6.19.1(eslint@8.56.0)(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-JvjfEZuP5WoMqwh9SPAPDSHSg9FBHHGhjPugSRxu5jMfjvBpq5/sGTD+9M9aQ5sh6iJ8AY/Kk/oUYVEMAPwi7w==}
|
||||
/@typescript-eslint/utils@7.0.2(eslint@8.56.0)(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-PZPIONBIB/X684bhT1XlrkjNZJIEevwkKDsdwfiu1WeqBxYEEdIgVDgm8/bbKHVu+6YOpeRqcfImTdImx/4Bsw==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
peerDependencies:
|
||||
eslint: ^7.0.0 || ^8.0.0
|
||||
eslint: ^8.56.0
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.4.0(eslint@8.56.0)
|
||||
'@types/json-schema': 7.0.15
|
||||
'@types/semver': 7.5.6
|
||||
'@typescript-eslint/scope-manager': 6.19.1
|
||||
'@typescript-eslint/types': 6.19.1
|
||||
'@typescript-eslint/typescript-estree': 6.19.1(typescript@5.3.3)
|
||||
'@types/semver': 7.5.7
|
||||
'@typescript-eslint/scope-manager': 7.0.2
|
||||
'@typescript-eslint/types': 7.0.2
|
||||
'@typescript-eslint/typescript-estree': 7.0.2(typescript@5.3.3)
|
||||
eslint: 8.56.0
|
||||
semver: 7.5.4
|
||||
semver: 7.6.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/visitor-keys@6.19.1:
|
||||
resolution: {integrity: sha512-gkdtIO+xSO/SmI0W68DBg4u1KElmIUo3vXzgHyGPs6cxgB0sa3TlptRAAE0hUY1hM6FcDKEv7aIwiTGm76cXfQ==}
|
||||
/@typescript-eslint/visitor-keys@7.0.2:
|
||||
resolution: {integrity: sha512-8Y+YiBmqPighbm5xA2k4wKTxRzx9EkBu7Rlw+WHqMvRJ3RPz/BMBO9b2ru0LUNmXg120PHUXD5+SWFy2R8DqlQ==}
|
||||
engines: {node: ^16.0.0 || >=18.0.0}
|
||||
dependencies:
|
||||
'@typescript-eslint/types': 6.19.1
|
||||
'@typescript-eslint/types': 7.0.2
|
||||
eslint-visitor-keys: 3.4.3
|
||||
dev: true
|
||||
|
||||
|
@ -1276,7 +1276,7 @@ packages:
|
|||
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
|
||||
dev: true
|
||||
|
||||
/create-jest@29.7.0(@types/node@20.11.10):
|
||||
/create-jest@29.7.0(@types/node@20.11.19):
|
||||
resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==}
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
hasBin: true
|
||||
|
@ -1285,7 +1285,7 @@ packages:
|
|||
chalk: 4.1.2
|
||||
exit: 0.1.2
|
||||
graceful-fs: 4.2.11
|
||||
jest-config: 29.7.0(@types/node@20.11.10)
|
||||
jest-config: 29.7.0(@types/node@20.11.19)
|
||||
jest-util: 29.7.0
|
||||
prompts: 2.4.2
|
||||
transitivePeerDependencies:
|
||||
|
@ -1295,8 +1295,8 @@ packages:
|
|||
- ts-node
|
||||
dev: true
|
||||
|
||||
/cross-fetch@3.1.8:
|
||||
resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==}
|
||||
/cross-fetch@4.0.0:
|
||||
resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==}
|
||||
dependencies:
|
||||
node-fetch: 2.7.0
|
||||
transitivePeerDependencies:
|
||||
|
@ -1414,7 +1414,7 @@ packages:
|
|||
engines: {node: '>=10'}
|
||||
dev: true
|
||||
|
||||
/eslint-plugin-prettier@5.1.3(eslint@8.56.0)(prettier@3.2.4):
|
||||
/eslint-plugin-prettier@5.1.3(eslint@8.56.0)(prettier@3.2.5):
|
||||
resolution: {integrity: sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==}
|
||||
engines: {node: ^14.18.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
|
@ -1429,7 +1429,7 @@ packages:
|
|||
optional: true
|
||||
dependencies:
|
||||
eslint: 8.56.0
|
||||
prettier: 3.2.4
|
||||
prettier: 3.2.5
|
||||
prettier-linter-helpers: 1.0.0
|
||||
synckit: 0.8.8
|
||||
dev: true
|
||||
|
@ -1735,7 +1735,7 @@ packages:
|
|||
array-union: 2.1.0
|
||||
dir-glob: 3.0.1
|
||||
fast-glob: 3.3.2
|
||||
ignore: 5.3.0
|
||||
ignore: 5.3.1
|
||||
merge2: 1.4.1
|
||||
slash: 3.0.0
|
||||
dev: true
|
||||
|
@ -1779,6 +1779,11 @@ packages:
|
|||
engines: {node: '>= 4'}
|
||||
dev: true
|
||||
|
||||
/ignore@5.3.1:
|
||||
resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==}
|
||||
engines: {node: '>= 4'}
|
||||
dev: true
|
||||
|
||||
/import-fresh@3.3.0:
|
||||
resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
|
||||
engines: {node: '>=6'}
|
||||
|
@ -1939,7 +1944,7 @@ packages:
|
|||
'@jest/expect': 29.7.0
|
||||
'@jest/test-result': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
'@types/node': 20.11.10
|
||||
'@types/node': 20.11.19
|
||||
chalk: 4.1.2
|
||||
co: 4.6.0
|
||||
dedent: 1.5.1
|
||||
|
@ -1960,7 +1965,7 @@ packages:
|
|||
- supports-color
|
||||
dev: true
|
||||
|
||||
/jest-cli@29.7.0(@types/node@20.11.10):
|
||||
/jest-cli@29.7.0(@types/node@20.11.19):
|
||||
resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==}
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
hasBin: true
|
||||
|
@ -1974,10 +1979,10 @@ packages:
|
|||
'@jest/test-result': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
chalk: 4.1.2
|
||||
create-jest: 29.7.0(@types/node@20.11.10)
|
||||
create-jest: 29.7.0(@types/node@20.11.19)
|
||||
exit: 0.1.2
|
||||
import-local: 3.1.0
|
||||
jest-config: 29.7.0(@types/node@20.11.10)
|
||||
jest-config: 29.7.0(@types/node@20.11.19)
|
||||
jest-util: 29.7.0
|
||||
jest-validate: 29.7.0
|
||||
yargs: 17.7.2
|
||||
|
@ -1988,7 +1993,7 @@ packages:
|
|||
- ts-node
|
||||
dev: true
|
||||
|
||||
/jest-config@29.7.0(@types/node@20.11.10):
|
||||
/jest-config@29.7.0(@types/node@20.11.19):
|
||||
resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==}
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
peerDependencies:
|
||||
|
@ -2003,7 +2008,7 @@ packages:
|
|||
'@babel/core': 7.23.9
|
||||
'@jest/test-sequencer': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
'@types/node': 20.11.10
|
||||
'@types/node': 20.11.19
|
||||
babel-jest: 29.7.0(@babel/core@7.23.9)
|
||||
chalk: 4.1.2
|
||||
ci-info: 3.9.0
|
||||
|
@ -2063,7 +2068,7 @@ packages:
|
|||
'@jest/environment': 29.7.0
|
||||
'@jest/fake-timers': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
'@types/node': 20.11.10
|
||||
'@types/node': 20.11.19
|
||||
jest-mock: 29.7.0
|
||||
jest-util: 29.7.0
|
||||
dev: true
|
||||
|
@ -2079,7 +2084,7 @@ packages:
|
|||
dependencies:
|
||||
'@jest/types': 29.6.3
|
||||
'@types/graceful-fs': 4.1.9
|
||||
'@types/node': 20.11.10
|
||||
'@types/node': 20.11.19
|
||||
anymatch: 3.1.3
|
||||
fb-watchman: 2.0.2
|
||||
graceful-fs: 4.2.11
|
||||
|
@ -2130,7 +2135,7 @@ packages:
|
|||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
dependencies:
|
||||
'@jest/types': 29.6.3
|
||||
'@types/node': 20.11.10
|
||||
'@types/node': 20.11.19
|
||||
jest-util: 29.7.0
|
||||
dev: true
|
||||
|
||||
|
@ -2185,7 +2190,7 @@ packages:
|
|||
'@jest/test-result': 29.7.0
|
||||
'@jest/transform': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
'@types/node': 20.11.10
|
||||
'@types/node': 20.11.19
|
||||
chalk: 4.1.2
|
||||
emittery: 0.13.1
|
||||
graceful-fs: 4.2.11
|
||||
|
@ -2216,7 +2221,7 @@ packages:
|
|||
'@jest/test-result': 29.7.0
|
||||
'@jest/transform': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
'@types/node': 20.11.10
|
||||
'@types/node': 20.11.19
|
||||
chalk: 4.1.2
|
||||
cjs-module-lexer: 1.2.3
|
||||
collect-v8-coverage: 1.0.2
|
||||
|
@ -2268,7 +2273,7 @@ packages:
|
|||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
dependencies:
|
||||
'@jest/types': 29.6.3
|
||||
'@types/node': 20.11.10
|
||||
'@types/node': 20.11.19
|
||||
chalk: 4.1.2
|
||||
ci-info: 3.9.0
|
||||
graceful-fs: 4.2.11
|
||||
|
@ -2293,7 +2298,7 @@ packages:
|
|||
dependencies:
|
||||
'@jest/test-result': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
'@types/node': 20.11.10
|
||||
'@types/node': 20.11.19
|
||||
ansi-escapes: 4.3.2
|
||||
chalk: 4.1.2
|
||||
emittery: 0.13.1
|
||||
|
@ -2305,13 +2310,13 @@ packages:
|
|||
resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==}
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
dependencies:
|
||||
'@types/node': 20.11.10
|
||||
'@types/node': 20.11.19
|
||||
jest-util: 29.7.0
|
||||
merge-stream: 2.0.0
|
||||
supports-color: 8.1.1
|
||||
dev: true
|
||||
|
||||
/jest@29.7.0(@types/node@20.11.10):
|
||||
/jest@29.7.0(@types/node@20.11.19):
|
||||
resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==}
|
||||
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
|
||||
hasBin: true
|
||||
|
@ -2324,7 +2329,7 @@ packages:
|
|||
'@jest/core': 29.7.0
|
||||
'@jest/types': 29.6.3
|
||||
import-local: 3.1.0
|
||||
jest-cli: 29.7.0(@types/node@20.11.10)
|
||||
jest-cli: 29.7.0(@types/node@20.11.19)
|
||||
transitivePeerDependencies:
|
||||
- '@types/node'
|
||||
- babel-plugin-macros
|
||||
|
@ -2390,10 +2395,10 @@ packages:
|
|||
engines: {node: '>=6'}
|
||||
dev: true
|
||||
|
||||
/lemmy-js-client@0.19.3-alpha.2:
|
||||
resolution: {integrity: sha512-bQZniRWyDKmVlk8b9Ec3KsQCK+qrlAXh208t8tOpMNVr2stA5GOZirp89gMf0Ep3I/GPwUwHtbVnVVlAt63q7g==}
|
||||
/lemmy-js-client@0.19.4-alpha.4:
|
||||
resolution: {integrity: sha512-ZsE/1dRiNAzOjGNtyv+1JH7AzKWBkHY4FH4EGrdhkKtNY7EKDWt4uEkc3Bde+cQg4YTdbzXyuY94gAVCFm+L1w==}
|
||||
dependencies:
|
||||
cross-fetch: 3.1.8
|
||||
cross-fetch: 4.0.0
|
||||
form-data: 4.0.0
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
|
@ -2687,8 +2692,8 @@ packages:
|
|||
fast-diff: 1.3.0
|
||||
dev: true
|
||||
|
||||
/prettier@3.2.4:
|
||||
resolution: {integrity: sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==}
|
||||
/prettier@3.2.5:
|
||||
resolution: {integrity: sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==}
|
||||
engines: {node: '>=14'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
@ -2794,6 +2799,14 @@ packages:
|
|||
lru-cache: 6.0.0
|
||||
dev: true
|
||||
|
||||
/semver@7.6.0:
|
||||
resolution: {integrity: sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==}
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
lru-cache: 6.0.0
|
||||
dev: true
|
||||
|
||||
/shebang-command@2.0.0:
|
||||
resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
|
||||
engines: {node: '>=8'}
|
||||
|
@ -2948,9 +2961,9 @@ packages:
|
|||
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
|
||||
dev: true
|
||||
|
||||
/ts-api-utils@1.0.3(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==}
|
||||
engines: {node: '>=16.13.0'}
|
||||
/ts-api-utils@1.2.1(typescript@5.3.3):
|
||||
resolution: {integrity: sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==}
|
||||
engines: {node: '>=16'}
|
||||
peerDependencies:
|
||||
typescript: '>=4.2.0'
|
||||
dependencies:
|
||||
|
@ -2981,7 +2994,7 @@ packages:
|
|||
'@babel/core': 7.23.9
|
||||
bs-logger: 0.2.6
|
||||
fast-json-stable-stringify: 2.1.0
|
||||
jest: 29.7.0(@types/node@20.11.10)
|
||||
jest: 29.7.0(@types/node@20.11.19)
|
||||
jest-util: 29.7.0
|
||||
json5: 2.2.3
|
||||
lodash.memoize: 4.1.2
|
||||
|
|
|
@ -14,7 +14,7 @@ export RUST_LOG="warn,lemmy_server=$LEMMY_LOG_LEVEL,lemmy_federate=$LEMMY_LOG_LE
|
|||
export LEMMY_TEST_FAST_FEDERATION=1 # by default, the persistent federation queue has delays in the scale of 30s-5min
|
||||
|
||||
# pictrs setup
|
||||
if [ ! -f "pict-rs" ]; then
|
||||
if [ ! -f "api_tests/pict-rs" ]; then
|
||||
curl "https://git.asonix.dog/asonix/pict-rs/releases/download/v0.5.0-beta.2/pict-rs-linux-amd64" -o api_tests/pict-rs
|
||||
chmod +x api_tests/pict-rs
|
||||
fi
|
||||
|
|
|
@ -29,9 +29,7 @@ import {
|
|||
delta,
|
||||
betaAllowedInstances,
|
||||
searchPostLocal,
|
||||
resolveBetaCommunity,
|
||||
longDelay,
|
||||
delay,
|
||||
editCommunity,
|
||||
} from "./shared";
|
||||
import { EditCommunity, EditSite } from "lemmy-js-client";
|
||||
|
|
|
@ -23,7 +23,6 @@ import {
|
|||
unfollowRemotes,
|
||||
resolvePerson,
|
||||
banPersonFromSite,
|
||||
searchPostLocal,
|
||||
followCommunity,
|
||||
banPersonFromCommunity,
|
||||
reportPost,
|
||||
|
@ -406,30 +405,34 @@ test("Search for a post", async () => {
|
|||
expect(betaPost?.post.name).toBeDefined();
|
||||
});
|
||||
|
||||
test("Enforce site ban for federated user", async () => {
|
||||
test("Enforce site ban federation for local user", async () => {
|
||||
if (!betaCommunity) {
|
||||
throw "Missing beta community";
|
||||
}
|
||||
|
||||
// create a test user
|
||||
let alpha_user = await registerUser(alpha, alphaUrl);
|
||||
let alphaUserPerson = (await getSite(alpha_user)).my_user?.local_user_view
|
||||
let alphaUserHttp = await registerUser(alpha, alphaUrl);
|
||||
let alphaUserPerson = (await getSite(alphaUserHttp)).my_user?.local_user_view
|
||||
.person;
|
||||
let alphaUserActorId = alphaUserPerson?.actor_id;
|
||||
if (!alphaUserActorId) {
|
||||
throw "Missing alpha user actor id";
|
||||
}
|
||||
expect(alphaUserActorId).toBeDefined();
|
||||
let alphaPerson = (await resolvePerson(alpha_user, alphaUserActorId!)).person;
|
||||
await followBeta(alphaUserHttp);
|
||||
|
||||
let alphaPerson = (await resolvePerson(alphaUserHttp, alphaUserActorId!))
|
||||
.person;
|
||||
if (!alphaPerson) {
|
||||
throw "Missing alpha person";
|
||||
}
|
||||
expect(alphaPerson).toBeDefined();
|
||||
|
||||
// alpha makes post in beta community, it federates to beta instance
|
||||
let postRes1 = await createPost(alpha_user, betaCommunity.community.id);
|
||||
let postRes1 = await createPost(alphaUserHttp, betaCommunity.community.id);
|
||||
let searchBeta1 = await waitForPost(beta, postRes1.post_view.post);
|
||||
|
||||
// ban alpha from its instance
|
||||
// ban alpha from its own instance
|
||||
let banAlpha = await banPersonFromSite(
|
||||
alpha,
|
||||
alphaPerson.person.id,
|
||||
|
@ -446,10 +449,11 @@ test("Enforce site ban for federated user", async () => {
|
|||
expect(alphaUserOnBeta1.person?.person.banned).toBe(true);
|
||||
|
||||
// existing alpha post should be removed on beta
|
||||
await waitUntil(
|
||||
let betaBanRes = await waitUntil(
|
||||
() => getPost(beta, searchBeta1.post.id),
|
||||
s => s.post_view.post.removed,
|
||||
);
|
||||
expect(betaBanRes.post_view.post.removed).toBe(true);
|
||||
|
||||
// Unban alpha
|
||||
let unBanAlpha = await banPersonFromSite(
|
||||
|
@ -465,21 +469,87 @@ test("Enforce site ban for federated user", async () => {
|
|||
throw "Missing alpha person";
|
||||
}
|
||||
let newAlphaUserJwt = await loginUser(alpha, alphaUserPerson.name);
|
||||
alpha_user.setHeaders({
|
||||
alphaUserHttp.setHeaders({
|
||||
Authorization: "Bearer " + newAlphaUserJwt.jwt ?? "",
|
||||
});
|
||||
// alpha makes new post in beta community, it federates
|
||||
let postRes2 = await createPost(alpha_user, betaCommunity!.community.id);
|
||||
let postRes2 = await createPost(alphaUserHttp, betaCommunity!.community.id);
|
||||
await waitForPost(beta, postRes2.post_view.post);
|
||||
|
||||
let alphaUserOnBeta2 = await resolvePerson(beta, alphaUserActorId!);
|
||||
expect(alphaUserOnBeta2.person?.person.banned).toBe(false);
|
||||
await unfollowRemotes(alpha);
|
||||
});
|
||||
|
||||
test.skip("Enforce community ban for federated user", async () => {
|
||||
test("Enforce site ban federation for federated user", async () => {
|
||||
if (!betaCommunity) {
|
||||
throw "Missing beta community";
|
||||
}
|
||||
|
||||
// create a test user
|
||||
let alphaUserHttp = await registerUser(alpha, alphaUrl);
|
||||
let alphaUserPerson = (await getSite(alphaUserHttp)).my_user?.local_user_view
|
||||
.person;
|
||||
let alphaUserActorId = alphaUserPerson?.actor_id;
|
||||
if (!alphaUserActorId) {
|
||||
throw "Missing alpha user actor id";
|
||||
}
|
||||
expect(alphaUserActorId).toBeDefined();
|
||||
await followBeta(alphaUserHttp);
|
||||
|
||||
let alphaUserOnBeta2 = await resolvePerson(beta, alphaUserActorId!);
|
||||
expect(alphaUserOnBeta2.person?.person.banned).toBe(false);
|
||||
|
||||
if (!alphaUserOnBeta2.person) {
|
||||
throw "Missing alpha person";
|
||||
}
|
||||
|
||||
// alpha makes post in beta community, it federates to beta instance
|
||||
let postRes1 = await createPost(alphaUserHttp, betaCommunity.community.id);
|
||||
let searchBeta1 = await waitForPost(beta, postRes1.post_view.post);
|
||||
expect(searchBeta1.post).toBeDefined();
|
||||
|
||||
// Now ban and remove their data from beta
|
||||
let banAlphaOnBeta = await banPersonFromSite(
|
||||
beta,
|
||||
alphaUserOnBeta2.person.person.id,
|
||||
true,
|
||||
true,
|
||||
);
|
||||
expect(banAlphaOnBeta.banned).toBe(true);
|
||||
|
||||
// The beta site ban should NOT be federated to alpha
|
||||
let alphaPerson2 = (await getSite(alphaUserHttp)).my_user?.local_user_view
|
||||
.person;
|
||||
if (!alphaPerson2) {
|
||||
throw "Missing alpha person";
|
||||
}
|
||||
expect(alphaPerson2.banned).toBe(false);
|
||||
|
||||
// existing alpha post should be removed on beta
|
||||
let betaBanRes = await waitUntil(
|
||||
() => getPost(beta, searchBeta1.post.id),
|
||||
s => s.post_view.post.removed,
|
||||
);
|
||||
expect(betaBanRes.post_view.post.removed).toBe(true);
|
||||
|
||||
// existing alpha's post to the beta community should be removed on alpha
|
||||
let alphaPostAfterRemoveOnBeta = await waitUntil(
|
||||
() => getPost(alpha, postRes1.post_view.post.id),
|
||||
s => s.post_view.post.removed,
|
||||
);
|
||||
expect(betaBanRes.post_view.post.removed).toBe(true);
|
||||
expect(alphaPostAfterRemoveOnBeta.post_view.post.removed).toBe(true);
|
||||
expect(
|
||||
alphaPostAfterRemoveOnBeta.post_view.creator_banned_from_community,
|
||||
).toBe(true);
|
||||
|
||||
await unfollowRemotes(alpha);
|
||||
});
|
||||
|
||||
test("Enforce community ban for federated user", async () => {
|
||||
if (!betaCommunity) {
|
||||
throw "Missing beta community";
|
||||
}
|
||||
await followBeta(alpha);
|
||||
let alphaShortname = `@lemmy_alpha@lemmy-alpha:8541`;
|
||||
let alphaPerson = (await resolvePerson(beta, alphaShortname)).person;
|
||||
if (!alphaPerson) {
|
||||
|
@ -489,38 +559,46 @@ test.skip("Enforce community ban for federated user", async () => {
|
|||
|
||||
// make a post in beta, it goes through
|
||||
let postRes1 = await createPost(alpha, betaCommunity.community.id);
|
||||
let searchBeta1 = await searchPostLocal(beta, postRes1.post_view.post);
|
||||
expect(searchBeta1.posts[0]).toBeDefined();
|
||||
let searchBeta1 = await waitForPost(beta, postRes1.post_view.post);
|
||||
expect(searchBeta1.post).toBeDefined();
|
||||
|
||||
// ban alpha from beta community
|
||||
let banAlpha = await banPersonFromCommunity(
|
||||
beta,
|
||||
alphaPerson.person.id,
|
||||
2,
|
||||
searchBeta1.community.id,
|
||||
true,
|
||||
true,
|
||||
);
|
||||
expect(banAlpha.banned).toBe(true);
|
||||
|
||||
// ensure that the post by alpha got removed
|
||||
await expect(getPost(alpha, searchBeta1.posts[0].post.id)).rejects.toBe(
|
||||
Error("unknown"),
|
||||
let removePostRes = await waitUntil(
|
||||
() => getPost(alpha, postRes1.post_view.post.id),
|
||||
s => s.post_view.post.removed,
|
||||
);
|
||||
expect(removePostRes.post_view.post.removed).toBe(true);
|
||||
expect(removePostRes.post_view.creator_banned_from_community).toBe(true);
|
||||
expect(removePostRes.community_view.banned_from_community).toBe(true);
|
||||
|
||||
// Alpha tries to make post on beta, but it fails because of ban
|
||||
await expect(createPost(alpha, betaCommunity.community.id)).rejects.toBe(
|
||||
Error("banned_from_community"),
|
||||
);
|
||||
await expect(
|
||||
createPost(alpha, betaCommunity.community.id),
|
||||
).rejects.toStrictEqual(Error("banned_from_community"));
|
||||
|
||||
// Unban alpha
|
||||
let unBanAlpha = await banPersonFromCommunity(
|
||||
beta,
|
||||
alphaPerson.person.id,
|
||||
2,
|
||||
searchBeta1.community.id,
|
||||
false,
|
||||
false,
|
||||
);
|
||||
expect(unBanAlpha.banned).toBe(false);
|
||||
|
||||
// Need to re-follow the community
|
||||
await followBeta(alpha);
|
||||
|
||||
let postRes3 = await createPost(alpha, betaCommunity.community.id);
|
||||
expect(postRes3.post_view.post).toBeDefined();
|
||||
expect(postRes3.post_view.community.local).toBe(false);
|
||||
|
@ -528,19 +606,25 @@ test.skip("Enforce community ban for federated user", async () => {
|
|||
expect(postRes3.post_view.counts.score).toBe(1);
|
||||
|
||||
// Make sure that post makes it to beta community
|
||||
let searchBeta2 = await searchPostLocal(beta, postRes3.post_view.post);
|
||||
expect(searchBeta2.posts[0]).toBeDefined();
|
||||
let postRes4 = await waitForPost(beta, postRes3.post_view.post);
|
||||
expect(postRes4.post).toBeDefined();
|
||||
expect(postRes4.creator_banned_from_community).toBe(false);
|
||||
|
||||
await unfollowRemotes(alpha);
|
||||
});
|
||||
|
||||
test("A and G subscribe to B (center) A posts, it gets announced to G", async () => {
|
||||
if (!betaCommunity) {
|
||||
throw "Missing beta community";
|
||||
}
|
||||
await followBeta(alpha);
|
||||
|
||||
let postRes = await createPost(alpha, betaCommunity.community.id);
|
||||
expect(postRes.post_view.post).toBeDefined();
|
||||
|
||||
let betaPost = (await resolvePost(gamma, postRes.post_view.post)).post;
|
||||
expect(betaPost?.post.name).toBeDefined();
|
||||
await unfollowRemotes(alpha);
|
||||
});
|
||||
|
||||
test("Report a post", async () => {
|
||||
|
@ -549,6 +633,7 @@ test("Report a post", async () => {
|
|||
if (!betaCommunity) {
|
||||
throw "Missing beta community";
|
||||
}
|
||||
await followBeta(alpha);
|
||||
let postRes = await createPost(beta, betaCommunity.community.id);
|
||||
expect(postRes.post_view.post).toBeDefined();
|
||||
|
||||
|
@ -576,9 +661,11 @@ test("Report a post", async () => {
|
|||
expect(betaReport.original_post_url).toBe(alphaReport.original_post_url);
|
||||
expect(betaReport.original_post_body).toBe(alphaReport.original_post_body);
|
||||
expect(betaReport.reason).toBe(alphaReport.reason);
|
||||
await unfollowRemotes(alpha);
|
||||
});
|
||||
|
||||
test("Fetch post via redirect", async () => {
|
||||
await followBeta(alpha);
|
||||
let alphaPost = await createPost(alpha, betaCommunity!.community.id);
|
||||
expect(alphaPost.post_view.post).toBeDefined();
|
||||
// Make sure that post is liked on beta
|
||||
|
@ -599,4 +686,5 @@ test("Fetch post via redirect", async () => {
|
|||
let gammaPost = await gamma.resolveObject(form);
|
||||
expect(gammaPost).toBeDefined();
|
||||
expect(gammaPost.post?.post.ap_id).toBe(alphaPost.post_view.post.ap_id);
|
||||
await unfollowRemotes(alpha);
|
||||
});
|
||||
|
|
|
@ -394,7 +394,7 @@ export async function banPersonFromSite(
|
|||
let form: BanPerson = {
|
||||
person_id,
|
||||
ban,
|
||||
remove_data: remove_data,
|
||||
remove_data,
|
||||
};
|
||||
return api.banPerson(form);
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ anyhow = { workspace = true }
|
|||
tracing = { workspace = true }
|
||||
chrono = { workspace = true }
|
||||
url = { workspace = true }
|
||||
itertools = { workspace = true }
|
||||
wav = "1.0.0"
|
||||
sitemap-rs = "0.2.0"
|
||||
totp-rs = { version = "5.5.1", features = ["gen_secret", "otpauth"] }
|
||||
|
|
|
@ -1,13 +1,22 @@
|
|||
use activitypub_federation::config::Data;
|
||||
use actix_web::{http::header::Header, HttpRequest};
|
||||
use actix_web_httpauth::headers::authorization::{Authorization, Bearer};
|
||||
use base64::{engine::general_purpose::STANDARD_NO_PAD as base64, Engine};
|
||||
use captcha::Captcha;
|
||||
use itertools::Itertools;
|
||||
use lemmy_api_common::{
|
||||
claims::Claims,
|
||||
community::BanFromCommunity,
|
||||
context::LemmyContext,
|
||||
send_activity::{ActivityChannel, SendActivityData},
|
||||
utils::{check_user_valid, local_site_to_slur_regex, AUTH_COOKIE_NAME},
|
||||
};
|
||||
use lemmy_db_schema::source::local_site::LocalSite;
|
||||
use lemmy_db_schema::source::{
|
||||
comment::Comment,
|
||||
local_site::LocalSite,
|
||||
person::Person,
|
||||
post::Post,
|
||||
};
|
||||
use lemmy_db_views::structs::LocalUserView;
|
||||
use lemmy_utils::{
|
||||
error::{LemmyError, LemmyErrorExt, LemmyErrorExt2, LemmyErrorType, LemmyResult},
|
||||
|
@ -141,6 +150,52 @@ pub(crate) fn build_totp_2fa(
|
|||
.with_lemmy_type(LemmyErrorType::CouldntGenerateTotp)
|
||||
}
|
||||
|
||||
/// Since removals and bans are only federated for local users,
|
||||
/// you also need to send bans for their content to local communities.
|
||||
/// See https://github.com/LemmyNet/lemmy/issues/4118
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub(crate) async fn send_bans_and_removals_to_local_communities(
|
||||
local_user_view: &LocalUserView,
|
||||
target: &Person,
|
||||
reason: &Option<String>,
|
||||
remove_data: &Option<bool>,
|
||||
context: &Data<LemmyContext>,
|
||||
) -> LemmyResult<()> {
|
||||
let posts_community_ids =
|
||||
Post::list_creators_local_community_ids(&mut context.pool(), target.id).await?;
|
||||
let comments_community_ids =
|
||||
Comment::list_creators_local_community_ids(&mut context.pool(), target.id).await?;
|
||||
|
||||
let ids = [posts_community_ids, comments_community_ids]
|
||||
.concat()
|
||||
.into_iter()
|
||||
.unique();
|
||||
|
||||
for community_id in ids {
|
||||
let ban_from_community = BanFromCommunity {
|
||||
community_id,
|
||||
person_id: target.id,
|
||||
ban: true,
|
||||
remove_data: *remove_data,
|
||||
reason: reason.clone(),
|
||||
expires: None,
|
||||
};
|
||||
|
||||
ActivityChannel::submit_activity(
|
||||
SendActivityData::BanFromCommunity {
|
||||
moderator: local_user_view.person.clone(),
|
||||
community_id,
|
||||
target: target.clone(),
|
||||
data: ban_from_community,
|
||||
},
|
||||
context,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip_all)]
|
||||
pub async fn local_user_view_from_jwt(
|
||||
jwt: &str,
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::send_bans_and_removals_to_local_communities;
|
||||
use activitypub_federation::config::Data;
|
||||
use actix_web::web::Json;
|
||||
use lemmy_api_common::{
|
||||
|
@ -47,7 +48,7 @@ pub async fn ban_from_site(
|
|||
.with_lemmy_type(LemmyErrorType::CouldntUpdateUser)?;
|
||||
|
||||
// if its a local user, invalidate logins
|
||||
let local_user = LocalUserView::read_person(&mut context.pool(), data.person_id).await;
|
||||
let local_user = LocalUserView::read_person(&mut context.pool(), person.id).await;
|
||||
if let Ok(local_user) = local_user {
|
||||
LoginToken::invalidate_all(&mut context.pool(), local_user.local_user.id).await?;
|
||||
}
|
||||
|
@ -61,7 +62,7 @@ pub async fn ban_from_site(
|
|||
// Mod tables
|
||||
let form = ModBanForm {
|
||||
mod_person_id: local_user_view.person.id,
|
||||
other_person_id: data.person_id,
|
||||
other_person_id: person.id,
|
||||
reason: data.reason.clone(),
|
||||
banned: Some(data.ban),
|
||||
expires,
|
||||
|
@ -69,7 +70,16 @@ pub async fn ban_from_site(
|
|||
|
||||
ModBan::create(&mut context.pool(), &form).await?;
|
||||
|
||||
let person_view = PersonView::read(&mut context.pool(), data.person_id).await?;
|
||||
let person_view = PersonView::read(&mut context.pool(), person.id).await?;
|
||||
|
||||
send_bans_and_removals_to_local_communities(
|
||||
&local_user_view,
|
||||
&person,
|
||||
&data.reason,
|
||||
&data.remove_data,
|
||||
&context,
|
||||
)
|
||||
.await?;
|
||||
|
||||
ActivityChannel::submit_activity(
|
||||
SendActivityData::BanFromSite {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
newtypes::{CommentId, DbUrl, PersonId},
|
||||
schema::comment::dsl::{ap_id, comment, content, creator_id, deleted, path, removed, updated},
|
||||
newtypes::{CommentId, CommunityId, DbUrl, PersonId},
|
||||
schema::{comment, community, post},
|
||||
source::comment::{
|
||||
Comment,
|
||||
CommentInsertForm,
|
||||
|
@ -17,6 +17,7 @@ use diesel::{
|
|||
dsl::{insert_into, sql_query},
|
||||
result::Error,
|
||||
ExpressionMethods,
|
||||
JoinOnDsl,
|
||||
QueryDsl,
|
||||
};
|
||||
use diesel_async::RunQueryDsl;
|
||||
|
@ -30,11 +31,11 @@ impl Comment {
|
|||
) -> Result<Vec<Self>, Error> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
|
||||
diesel::update(comment.filter(creator_id.eq(for_creator_id)))
|
||||
diesel::update(comment::table.filter(comment::creator_id.eq(for_creator_id)))
|
||||
.set((
|
||||
content.eq(DELETED_REPLACEMENT_TEXT),
|
||||
deleted.eq(true),
|
||||
updated.eq(naive_now()),
|
||||
comment::content.eq(DELETED_REPLACEMENT_TEXT),
|
||||
comment::deleted.eq(true),
|
||||
comment::updated.eq(naive_now()),
|
||||
))
|
||||
.get_results::<Self>(conn)
|
||||
.await
|
||||
|
@ -46,12 +47,32 @@ impl Comment {
|
|||
new_removed: bool,
|
||||
) -> Result<Vec<Self>, Error> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
diesel::update(comment.filter(creator_id.eq(for_creator_id)))
|
||||
.set((removed.eq(new_removed), updated.eq(naive_now())))
|
||||
diesel::update(comment::table.filter(comment::creator_id.eq(for_creator_id)))
|
||||
.set((
|
||||
comment::removed.eq(new_removed),
|
||||
comment::updated.eq(naive_now()),
|
||||
))
|
||||
.get_results::<Self>(conn)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Lists local community ids for all comments for a given creator.
|
||||
pub async fn list_creators_local_community_ids(
|
||||
pool: &mut DbPool<'_>,
|
||||
for_creator_id: PersonId,
|
||||
) -> Result<Vec<CommunityId>, Error> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
comment::table
|
||||
.inner_join(post::table)
|
||||
.inner_join(community::table.on(post::community_id.eq(community::id)))
|
||||
.filter(community::local.eq(true))
|
||||
.filter(comment::creator_id.eq(for_creator_id))
|
||||
.select(community::id)
|
||||
.distinct()
|
||||
.load::<CommunityId>(conn)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn create(
|
||||
pool: &mut DbPool<'_>,
|
||||
comment_form: &CommentInsertForm,
|
||||
|
@ -64,9 +85,9 @@ impl Comment {
|
|||
.run(|conn| {
|
||||
Box::pin(async move {
|
||||
// Insert, to get the id
|
||||
let inserted_comment = insert_into(comment)
|
||||
let inserted_comment = insert_into(comment::table)
|
||||
.values(comment_form)
|
||||
.on_conflict(ap_id)
|
||||
.on_conflict(comment::ap_id)
|
||||
.do_update()
|
||||
.set(comment_form)
|
||||
.get_result::<Self>(conn)
|
||||
|
@ -84,8 +105,8 @@ impl Comment {
|
|||
format!("{}.{}", 0, comment_id)
|
||||
});
|
||||
|
||||
let updated_comment = diesel::update(comment.find(comment_id))
|
||||
.set(path.eq(ltree))
|
||||
let updated_comment = diesel::update(comment::table.find(comment_id))
|
||||
.set(comment::path.eq(ltree))
|
||||
.get_result::<Self>(conn)
|
||||
.await?;
|
||||
|
||||
|
@ -133,8 +154,8 @@ where ca.comment_id = c.id"
|
|||
let conn = &mut get_conn(pool).await?;
|
||||
let object_id: DbUrl = object_id.into();
|
||||
Ok(
|
||||
comment
|
||||
.filter(ap_id.eq(object_id))
|
||||
comment::table
|
||||
.filter(comment::ap_id.eq(object_id))
|
||||
.first::<Comment>(conn)
|
||||
.await
|
||||
.ok()
|
||||
|
@ -171,7 +192,7 @@ impl Crud for Comment {
|
|||
comment_form: &Self::UpdateForm,
|
||||
) -> Result<Self, Error> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
diesel::update(comment.find(comment_id))
|
||||
diesel::update(comment::table.find(comment_id))
|
||||
.set(comment_form)
|
||||
.get_result::<Self>(conn)
|
||||
.await
|
||||
|
|
|
@ -1,21 +1,6 @@
|
|||
use crate::{
|
||||
newtypes::{CommunityId, DbUrl, PersonId, PostId},
|
||||
schema::post::dsl::{
|
||||
ap_id,
|
||||
body,
|
||||
community_id,
|
||||
creator_id,
|
||||
deleted,
|
||||
featured_community,
|
||||
local,
|
||||
name,
|
||||
post,
|
||||
published,
|
||||
removed,
|
||||
thumbnail_url,
|
||||
updated,
|
||||
url,
|
||||
},
|
||||
schema::{community, post},
|
||||
source::post::{
|
||||
Post,
|
||||
PostInsertForm,
|
||||
|
@ -53,9 +38,9 @@ impl Crud for Post {
|
|||
|
||||
async fn create(pool: &mut DbPool<'_>, form: &Self::InsertForm) -> Result<Self, Error> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
insert_into(post)
|
||||
insert_into(post::table)
|
||||
.values(form)
|
||||
.on_conflict(ap_id)
|
||||
.on_conflict(post::ap_id)
|
||||
.do_update()
|
||||
.set(form)
|
||||
.get_result::<Self>(conn)
|
||||
|
@ -68,7 +53,7 @@ impl Crud for Post {
|
|||
new_post: &Self::UpdateForm,
|
||||
) -> Result<Self, Error> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
diesel::update(post.find(post_id))
|
||||
diesel::update(post::table.find(post_id))
|
||||
.set(new_post)
|
||||
.get_result::<Self>(conn)
|
||||
.await
|
||||
|
@ -81,12 +66,12 @@ impl Post {
|
|||
the_community_id: CommunityId,
|
||||
) -> Result<Vec<Self>, Error> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
post
|
||||
.filter(community_id.eq(the_community_id))
|
||||
.filter(deleted.eq(false))
|
||||
.filter(removed.eq(false))
|
||||
.then_order_by(featured_community.desc())
|
||||
.then_order_by(published.desc())
|
||||
post::table
|
||||
.filter(post::community_id.eq(the_community_id))
|
||||
.filter(post::deleted.eq(false))
|
||||
.filter(post::removed.eq(false))
|
||||
.then_order_by(post::featured_community.desc())
|
||||
.then_order_by(post::published.desc())
|
||||
.limit(FETCH_LIMIT_MAX)
|
||||
.load::<Self>(conn)
|
||||
.await
|
||||
|
@ -97,12 +82,12 @@ impl Post {
|
|||
the_community_id: CommunityId,
|
||||
) -> Result<Vec<Self>, Error> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
post
|
||||
.filter(community_id.eq(the_community_id))
|
||||
.filter(deleted.eq(false))
|
||||
.filter(removed.eq(false))
|
||||
.filter(featured_community.eq(true))
|
||||
.then_order_by(published.desc())
|
||||
post::table
|
||||
.filter(post::community_id.eq(the_community_id))
|
||||
.filter(post::deleted.eq(false))
|
||||
.filter(post::removed.eq(false))
|
||||
.filter(post::featured_community.eq(true))
|
||||
.then_order_by(post::published.desc())
|
||||
.limit(FETCH_LIMIT_MAX)
|
||||
.load::<Self>(conn)
|
||||
.await
|
||||
|
@ -112,13 +97,13 @@ impl Post {
|
|||
pool: &mut DbPool<'_>,
|
||||
) -> Result<Vec<(DbUrl, chrono::DateTime<Utc>)>, Error> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
post
|
||||
.select((ap_id, coalesce(updated, published)))
|
||||
.filter(local.eq(true))
|
||||
.filter(deleted.eq(false))
|
||||
.filter(removed.eq(false))
|
||||
.filter(published.ge(Utc::now().naive_utc() - Duration::days(SITEMAP_DAYS)))
|
||||
.order(published.desc())
|
||||
post::table
|
||||
.select((post::ap_id, coalesce(post::updated, post::published)))
|
||||
.filter(post::local.eq(true))
|
||||
.filter(post::deleted.eq(false))
|
||||
.filter(post::removed.eq(false))
|
||||
.filter(post::published.ge(Utc::now().naive_utc() - Duration::days(SITEMAP_DAYS)))
|
||||
.order(post::published.desc())
|
||||
.limit(SITEMAP_LIMIT)
|
||||
.load::<(DbUrl, chrono::DateTime<Utc>)>(conn)
|
||||
.await
|
||||
|
@ -130,13 +115,13 @@ impl Post {
|
|||
) -> Result<Vec<Self>, Error> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
|
||||
diesel::update(post.filter(creator_id.eq(for_creator_id)))
|
||||
diesel::update(post::table.filter(post::creator_id.eq(for_creator_id)))
|
||||
.set((
|
||||
name.eq(DELETED_REPLACEMENT_TEXT),
|
||||
url.eq(Option::<&str>::None),
|
||||
body.eq(DELETED_REPLACEMENT_TEXT),
|
||||
deleted.eq(true),
|
||||
updated.eq(naive_now()),
|
||||
post::name.eq(DELETED_REPLACEMENT_TEXT),
|
||||
post::url.eq(Option::<&str>::None),
|
||||
post::body.eq(DELETED_REPLACEMENT_TEXT),
|
||||
post::deleted.eq(true),
|
||||
post::updated.eq(naive_now()),
|
||||
))
|
||||
.get_results::<Self>(conn)
|
||||
.await
|
||||
|
@ -150,15 +135,15 @@ impl Post {
|
|||
) -> Result<Vec<Self>, Error> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
|
||||
let mut update = diesel::update(post).into_boxed();
|
||||
update = update.filter(creator_id.eq(for_creator_id));
|
||||
let mut update = diesel::update(post::table).into_boxed();
|
||||
update = update.filter(post::creator_id.eq(for_creator_id));
|
||||
|
||||
if let Some(for_community_id) = for_community_id {
|
||||
update = update.filter(community_id.eq(for_community_id));
|
||||
update = update.filter(post::community_id.eq(for_community_id));
|
||||
}
|
||||
|
||||
update
|
||||
.set((removed.eq(new_removed), updated.eq(naive_now())))
|
||||
.set((post::removed.eq(new_removed), post::updated.eq(naive_now())))
|
||||
.get_results::<Self>(conn)
|
||||
.await
|
||||
}
|
||||
|
@ -174,8 +159,8 @@ impl Post {
|
|||
let conn = &mut get_conn(pool).await?;
|
||||
let object_id: DbUrl = object_id.into();
|
||||
Ok(
|
||||
post
|
||||
.filter(ap_id.eq(object_id))
|
||||
post::table
|
||||
.filter(post::ap_id.eq(object_id))
|
||||
.first::<Post>(conn)
|
||||
.await
|
||||
.ok()
|
||||
|
@ -190,9 +175,9 @@ impl Post {
|
|||
let conn = &mut get_conn(pool).await?;
|
||||
let pictrs_search = "%pictrs/image%";
|
||||
|
||||
post
|
||||
.filter(creator_id.eq(for_creator_id))
|
||||
.filter(url.like(pictrs_search))
|
||||
post::table
|
||||
.filter(post::creator_id.eq(for_creator_id))
|
||||
.filter(post::url.like(pictrs_search))
|
||||
.load::<Self>(conn)
|
||||
.await
|
||||
}
|
||||
|
@ -206,13 +191,13 @@ impl Post {
|
|||
let pictrs_search = "%pictrs/image%";
|
||||
|
||||
diesel::update(
|
||||
post
|
||||
.filter(creator_id.eq(for_creator_id))
|
||||
.filter(url.like(pictrs_search)),
|
||||
post::table
|
||||
.filter(post::creator_id.eq(for_creator_id))
|
||||
.filter(post::url.like(pictrs_search)),
|
||||
)
|
||||
.set((
|
||||
url.eq::<Option<String>>(None),
|
||||
thumbnail_url.eq::<Option<String>>(None),
|
||||
post::url.eq::<Option<String>>(None),
|
||||
post::thumbnail_url.eq::<Option<String>>(None),
|
||||
))
|
||||
.get_results::<Self>(conn)
|
||||
.await
|
||||
|
@ -224,9 +209,9 @@ impl Post {
|
|||
) -> Result<Vec<Self>, Error> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
let pictrs_search = "%pictrs/image%";
|
||||
post
|
||||
.filter(community_id.eq(for_community_id))
|
||||
.filter(url.like(pictrs_search))
|
||||
post::table
|
||||
.filter(post::community_id.eq(for_community_id))
|
||||
.filter(post::url.like(pictrs_search))
|
||||
.load::<Self>(conn)
|
||||
.await
|
||||
}
|
||||
|
@ -240,17 +225,33 @@ impl Post {
|
|||
let pictrs_search = "%pictrs/image%";
|
||||
|
||||
diesel::update(
|
||||
post
|
||||
.filter(community_id.eq(for_community_id))
|
||||
.filter(url.like(pictrs_search)),
|
||||
post::table
|
||||
.filter(post::community_id.eq(for_community_id))
|
||||
.filter(post::url.like(pictrs_search)),
|
||||
)
|
||||
.set((
|
||||
url.eq::<Option<String>>(None),
|
||||
thumbnail_url.eq::<Option<String>>(None),
|
||||
post::url.eq::<Option<String>>(None),
|
||||
post::thumbnail_url.eq::<Option<String>>(None),
|
||||
))
|
||||
.get_results::<Self>(conn)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Lists local community ids for all posts for a given creator.
|
||||
pub async fn list_creators_local_community_ids(
|
||||
pool: &mut DbPool<'_>,
|
||||
for_creator_id: PersonId,
|
||||
) -> Result<Vec<CommunityId>, Error> {
|
||||
let conn = &mut get_conn(pool).await?;
|
||||
post::table
|
||||
.inner_join(community::table)
|
||||
.filter(community::local.eq(true))
|
||||
.filter(post::creator_id.eq(for_creator_id))
|
||||
.select(community::id)
|
||||
.distinct()
|
||||
.load::<CommunityId>(conn)
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
|
|
Loading…
Reference in New Issue