mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-12-22 10:51:29 +00:00
* Reorganize api endpoints (fixes #2022) * scopes * move message rate limit * move rate limit * apply suggestions * move my_user to separate endpoint * remove taglines and custom emojis from siteview * routes for api v3 and v4 * remove new features from api v3 * js client * replace occurences of `v3`, fix routes * replace getSite().my_user with getMyUser() * update * update config * remove web:: * update * prettier * lockfile * v * fix settings * move block endpoints * more changes * fmt * update * change some routes * lockfile * Add comment about deprecation
This commit is contained in:
parent
adadb45ace
commit
5e7b30ac6a
29 changed files with 558 additions and 216 deletions
|
@ -28,7 +28,7 @@
|
|||
"eslint": "^9.14.0",
|
||||
"eslint-plugin-prettier": "^5.1.3",
|
||||
"jest": "^29.5.0",
|
||||
"lemmy-js-client": "0.20.0-instance-blocks.5",
|
||||
"lemmy-js-client": "0.20.0-api-v4.16",
|
||||
"prettier": "^3.2.5",
|
||||
"ts-jest": "^29.1.0",
|
||||
"typescript": "^5.5.4",
|
||||
|
|
|
@ -30,8 +30,8 @@ importers:
|
|||
specifier: ^29.5.0
|
||||
version: 29.7.0(@types/node@22.9.0)
|
||||
lemmy-js-client:
|
||||
specifier: 0.20.0-instance-blocks.5
|
||||
version: 0.20.0-instance-blocks.5
|
||||
specifier: 0.20.0-api-v4.16
|
||||
version: 0.20.0-api-v4.16
|
||||
prettier:
|
||||
specifier: ^3.2.5
|
||||
version: 3.3.3
|
||||
|
@ -1167,8 +1167,8 @@ packages:
|
|||
resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
lemmy-js-client@0.20.0-instance-blocks.5:
|
||||
resolution: {integrity: sha512-wDuRFzg32lbbJr4cNmd+cbzjgw+okw2/d5AujYjAm4gv0OEFfsYhP3QQ2WscwUR5HJTdzsR7IIyiBnvmaEUzUw==}
|
||||
lemmy-js-client@0.20.0-api-v4.16:
|
||||
resolution: {integrity: sha512-9Wn7b8YT2KnEA286+RV1B3mLmecAynvAERoC0ZZiccfSgkEvd3rG9A5X9ejiPqp+JzDZJeisO57+Ut4QHr5oTw==}
|
||||
|
||||
leven@3.1.0:
|
||||
resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==}
|
||||
|
@ -3077,7 +3077,7 @@ snapshots:
|
|||
|
||||
kleur@3.0.3: {}
|
||||
|
||||
lemmy-js-client@0.20.0-instance-blocks.5: {}
|
||||
lemmy-js-client@0.20.0-api-v4.16: {}
|
||||
|
||||
leven@3.1.0: {}
|
||||
|
||||
|
|
|
@ -82,13 +82,13 @@ LEMMY_CONFIG_LOCATION=./docker/federation/lemmy_epsilon.hjson \
|
|||
target/lemmy_server >$LOG_DIR/lemmy_epsilon.out 2>&1 &
|
||||
|
||||
echo "wait for all instances to start"
|
||||
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'lemmy-alpha:8541/api/v3/site')" != "200" ]]; do sleep 1; done
|
||||
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'lemmy-alpha:8541/api/v4/site')" != "200" ]]; do sleep 1; done
|
||||
echo "alpha started"
|
||||
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'lemmy-beta:8551/api/v3/site')" != "200" ]]; do sleep 1; done
|
||||
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'lemmy-beta:8551/api/v4/site')" != "200" ]]; do sleep 1; done
|
||||
echo "beta started"
|
||||
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'lemmy-gamma:8561/api/v3/site')" != "200" ]]; do sleep 1; done
|
||||
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'lemmy-gamma:8561/api/v4/site')" != "200" ]]; do sleep 1; done
|
||||
echo "gamma started"
|
||||
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'lemmy-delta:8571/api/v3/site')" != "200" ]]; do sleep 1; done
|
||||
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'lemmy-delta:8571/api/v4/site')" != "200" ]]; do sleep 1; done
|
||||
echo "delta started"
|
||||
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'lemmy-epsilon:8581/api/v3/site')" != "200" ]]; do sleep 1; done
|
||||
while [[ "$(curl -s -o /dev/null -w '%{http_code}' 'lemmy-epsilon:8581/api/v4/site')" != "200" ]]; do sleep 1; done
|
||||
echo "epsilon started. All started"
|
||||
|
|
|
@ -699,10 +699,10 @@ test("Check that activity from another instance is sent to third instance", asyn
|
|||
|
||||
test("Fetch in_reply_tos: A is unsubbed from B, B makes a post, and some embedded comments, A subs to B, B updates the lowest level comment, A fetches both the post and all the inreplyto comments for that post.", async () => {
|
||||
// Unfollow all remote communities
|
||||
let site = await unfollowRemotes(alpha);
|
||||
expect(
|
||||
site.my_user?.follows.filter(c => c.community.local == false).length,
|
||||
).toBe(0);
|
||||
let my_user = await unfollowRemotes(alpha);
|
||||
expect(my_user.follows.filter(c => c.community.local == false).length).toBe(
|
||||
0,
|
||||
);
|
||||
|
||||
// B creates a post, and two comments, should be invisible to A
|
||||
let postOnBetaRes = await createPost(beta, 2);
|
||||
|
|
|
@ -32,6 +32,7 @@ import {
|
|||
longDelay,
|
||||
editCommunity,
|
||||
unfollows,
|
||||
getMyUser,
|
||||
userBlockInstance,
|
||||
} from "./shared";
|
||||
import { AdminAllowInstanceParams } from "lemmy-js-client/dist/types/AdminAllowInstanceParams";
|
||||
|
@ -226,7 +227,7 @@ test("Admin actions in remote community are not federated to origin", async () =
|
|||
if (!betaCommunity) {
|
||||
throw "Missing beta community";
|
||||
}
|
||||
let bannedUserInfo1 = (await getSite(gamma)).my_user?.local_user_view.person;
|
||||
let bannedUserInfo1 = (await getMyUser(gamma)).local_user_view.person;
|
||||
if (!bannedUserInfo1) {
|
||||
throw "Missing banned user 1";
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import {
|
|||
registerUser,
|
||||
unfollows,
|
||||
delay,
|
||||
getMyUser,
|
||||
} from "./shared";
|
||||
|
||||
beforeAll(setupLogins);
|
||||
|
@ -85,8 +86,8 @@ test("Follow federated community", async () => {
|
|||
);
|
||||
|
||||
// Check it from local
|
||||
let site = await getSite(alpha);
|
||||
let remoteCommunityId = site.my_user?.follows.find(
|
||||
let my_user = await getMyUser(alpha);
|
||||
let remoteCommunityId = my_user?.follows.find(
|
||||
c =>
|
||||
c.community.local == false &&
|
||||
c.community.id === betaCommunityInitial.community.id,
|
||||
|
@ -102,9 +103,9 @@ test("Follow federated community", async () => {
|
|||
expect(unfollow.community_view.subscribed).toBe("NotSubscribed");
|
||||
|
||||
// Make sure you are unsubbed locally
|
||||
let siteUnfollowCheck = await getSite(alpha);
|
||||
let siteUnfollowCheck = await getMyUser(alpha);
|
||||
expect(
|
||||
siteUnfollowCheck.my_user?.follows.find(
|
||||
siteUnfollowCheck.follows.find(
|
||||
c => c.community.id === betaCommunityInitial.community.id,
|
||||
),
|
||||
).toBe(undefined);
|
||||
|
|
|
@ -32,6 +32,7 @@ import {
|
|||
createPostWithThumbnail,
|
||||
sampleImage,
|
||||
sampleSite,
|
||||
getMyUser,
|
||||
} from "./shared";
|
||||
|
||||
beforeAll(setupLogins);
|
||||
|
@ -129,9 +130,9 @@ test("Purge user, uploaded image removed", async () => {
|
|||
expect(content.length).toBeGreaterThan(0);
|
||||
|
||||
// purge user
|
||||
let site = await getSite(user);
|
||||
let my_user = await getMyUser(user);
|
||||
const purgeForm: PurgePerson = {
|
||||
person_id: site.my_user!.local_user_view.person.id,
|
||||
person_id: my_user.local_user_view.person.id,
|
||||
};
|
||||
const delete_ = await alphaImage.purgePerson(purgeForm);
|
||||
expect(delete_.success).toBe(true);
|
||||
|
@ -199,11 +200,11 @@ test("Images in remote image post are proxied if setting enabled", async () => {
|
|||
// remote image gets proxied after upload
|
||||
expect(
|
||||
post.thumbnail_url?.startsWith(
|
||||
"http://lemmy-gamma:8561/api/v3/image_proxy?url",
|
||||
"http://lemmy-gamma:8561/api/v4/image_proxy?url",
|
||||
),
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
post.body?.startsWith("![](http://lemmy-gamma:8561/api/v3/image_proxy?url"),
|
||||
post.body?.startsWith("![](http://lemmy-gamma:8561/api/v4/image_proxy?url"),
|
||||
).toBeTruthy();
|
||||
|
||||
// Make sure that it ends with jpg, to be sure its an image
|
||||
|
@ -222,12 +223,12 @@ test("Images in remote image post are proxied if setting enabled", async () => {
|
|||
|
||||
expect(
|
||||
epsilonPost.thumbnail_url?.startsWith(
|
||||
"http://lemmy-epsilon:8581/api/v3/image_proxy?url",
|
||||
"http://lemmy-epsilon:8581/api/v4/image_proxy?url",
|
||||
),
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
epsilonPost.body?.startsWith(
|
||||
"![](http://lemmy-epsilon:8581/api/v3/image_proxy?url",
|
||||
"![](http://lemmy-epsilon:8581/api/v4/image_proxy?url",
|
||||
),
|
||||
).toBeTruthy();
|
||||
|
||||
|
@ -249,7 +250,7 @@ test("Thumbnail of remote image link is proxied if setting enabled", async () =>
|
|||
// remote image gets proxied after upload
|
||||
expect(
|
||||
post.thumbnail_url?.startsWith(
|
||||
"http://lemmy-gamma:8561/api/v3/image_proxy?url",
|
||||
"http://lemmy-gamma:8561/api/v4/image_proxy?url",
|
||||
),
|
||||
).toBeTruthy();
|
||||
|
||||
|
@ -267,7 +268,7 @@ test("Thumbnail of remote image link is proxied if setting enabled", async () =>
|
|||
|
||||
expect(
|
||||
epsilonPost.thumbnail_url?.startsWith(
|
||||
"http://lemmy-epsilon:8581/api/v3/image_proxy?url",
|
||||
"http://lemmy-epsilon:8581/api/v4/image_proxy?url",
|
||||
),
|
||||
).toBeTruthy();
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ import {
|
|||
alphaUrl,
|
||||
loginUser,
|
||||
createCommunity,
|
||||
getMyUser,
|
||||
} from "./shared";
|
||||
import { PostView } from "lemmy-js-client/dist/types/PostView";
|
||||
import { AdminBlockInstanceParams } from "lemmy-js-client/dist/types/AdminBlockInstanceParams";
|
||||
|
@ -451,8 +452,7 @@ test("Enforce site ban federation for local user", async () => {
|
|||
|
||||
// create a test user
|
||||
let alphaUserHttp = await registerUser(alpha, alphaUrl);
|
||||
let alphaUserPerson = (await getSite(alphaUserHttp)).my_user?.local_user_view
|
||||
.person;
|
||||
let alphaUserPerson = (await getMyUser(alphaUserHttp)).local_user_view.person;
|
||||
let alphaUserActorId = alphaUserPerson?.actor_id;
|
||||
if (!alphaUserActorId) {
|
||||
throw "Missing alpha user actor id";
|
||||
|
@ -532,8 +532,7 @@ test("Enforce site ban federation for federated user", async () => {
|
|||
|
||||
// create a test user
|
||||
let alphaUserHttp = await registerUser(alpha, alphaUrl);
|
||||
let alphaUserPerson = (await getSite(alphaUserHttp)).my_user?.local_user_view
|
||||
.person;
|
||||
let alphaUserPerson = (await getMyUser(alphaUserHttp)).local_user_view.person;
|
||||
let alphaUserActorId = alphaUserPerson?.actor_id;
|
||||
if (!alphaUserActorId) {
|
||||
throw "Missing alpha user actor id";
|
||||
|
@ -563,8 +562,7 @@ test("Enforce site ban federation for federated user", async () => {
|
|||
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;
|
||||
let alphaPerson2 = (await getMyUser(alphaUserHttp)).local_user_view.person;
|
||||
expect(alphaPerson2.banned).toBe(false);
|
||||
|
||||
// existing alpha post should be removed on beta
|
||||
|
|
|
@ -16,6 +16,7 @@ import {
|
|||
LemmyHttp,
|
||||
ListCommunityPendingFollows,
|
||||
ListCommunityPendingFollowsResponse,
|
||||
MyUserInfo,
|
||||
PersonId,
|
||||
PostView,
|
||||
PrivateMessageReportResponse,
|
||||
|
@ -761,6 +762,10 @@ export async function getSite(api: LemmyHttp): Promise<GetSiteResponse> {
|
|||
return api.getSite();
|
||||
}
|
||||
|
||||
export async function getMyUser(api: LemmyHttp): Promise<MyUserInfo> {
|
||||
return api.getMyUser();
|
||||
}
|
||||
|
||||
export async function listPrivateMessages(
|
||||
api: LemmyHttp,
|
||||
): Promise<PrivateMessagesResponse> {
|
||||
|
@ -770,19 +775,16 @@ export async function listPrivateMessages(
|
|||
return api.getPrivateMessages(form);
|
||||
}
|
||||
|
||||
export async function unfollowRemotes(
|
||||
api: LemmyHttp,
|
||||
): Promise<GetSiteResponse> {
|
||||
export async function unfollowRemotes(api: LemmyHttp): Promise<MyUserInfo> {
|
||||
// Unfollow all remote communities
|
||||
let site = await getSite(api);
|
||||
let my_user = await getMyUser(api);
|
||||
let remoteFollowed =
|
||||
site.my_user?.follows.filter(c => c.community.local == false) ?? [];
|
||||
my_user.follows.filter(c => c.community.local == false) ?? [];
|
||||
await Promise.all(
|
||||
remoteFollowed.map(cu => followCommunity(api, false, cu.community.id)),
|
||||
);
|
||||
|
||||
let siteRes = await getSite(api);
|
||||
return siteRes;
|
||||
return await getMyUser(api);
|
||||
}
|
||||
|
||||
export async function followBeta(api: LemmyHttp): Promise<CommunityResponse> {
|
||||
|
|
|
@ -22,6 +22,7 @@ import {
|
|||
alphaImage,
|
||||
unfollows,
|
||||
saveUserSettingsBio,
|
||||
getMyUser,
|
||||
getPersonDetails,
|
||||
} from "./shared";
|
||||
import {
|
||||
|
@ -50,12 +51,9 @@ function assertUserFederation(userOne?: PersonView, userTwo?: PersonView) {
|
|||
test("Create user", async () => {
|
||||
let user = await registerUser(alpha, alphaUrl);
|
||||
|
||||
let site = await getSite(user);
|
||||
expect(site.my_user).toBeDefined();
|
||||
if (!site.my_user) {
|
||||
throw "Missing site user";
|
||||
}
|
||||
apShortname = `${site.my_user.local_user_view.person.name}@lemmy-alpha:8541`;
|
||||
let my_user = await getMyUser(user);
|
||||
expect(my_user).toBeDefined();
|
||||
apShortname = `${my_user.local_user_view.person.name}@lemmy-alpha:8541`;
|
||||
});
|
||||
|
||||
test("Set some user settings, check that they are federated", async () => {
|
||||
|
@ -70,8 +68,8 @@ test("Set some user settings, check that they are federated", async () => {
|
|||
};
|
||||
await saveUserSettings(beta, form);
|
||||
|
||||
let site = await getSite(beta);
|
||||
expect(site.my_user?.local_user_view.local_user.theme).toBe("test");
|
||||
let my_user = await getMyUser(beta);
|
||||
expect(my_user.local_user_view.local_user.theme).toBe("test");
|
||||
});
|
||||
|
||||
test("Delete user", async () => {
|
||||
|
@ -127,8 +125,10 @@ test("Requests with invalid auth should be treated as unauthenticated", async ()
|
|||
headers: { Authorization: "Bearer foobar" },
|
||||
fetchFunction,
|
||||
});
|
||||
await expect(getMyUser(invalid_auth)).rejects.toStrictEqual(
|
||||
Error("incorrect_login"),
|
||||
);
|
||||
let site = await getSite(invalid_auth);
|
||||
expect(site.my_user).toBeUndefined();
|
||||
expect(site.site_view).toBeDefined();
|
||||
|
||||
let form: GetPosts = {};
|
||||
|
@ -141,12 +141,9 @@ test("Create user with Arabic name", async () => {
|
|||
const name = "تجريب" + Math.random().toString().slice(2, 10);
|
||||
let user = await registerUser(alpha, alphaUrl, name);
|
||||
|
||||
let site = await getSite(user);
|
||||
expect(site.my_user).toBeDefined();
|
||||
if (!site.my_user) {
|
||||
throw "Missing site user";
|
||||
}
|
||||
apShortname = `${site.my_user.local_user_view.person.name}@lemmy-alpha:8541`;
|
||||
let my_user = await getMyUser(user);
|
||||
expect(my_user).toBeDefined();
|
||||
apShortname = `${my_user.local_user_view.person.name}@lemmy-alpha:8541`;
|
||||
|
||||
let betaPerson1 = (await resolvePerson(beta, apShortname)).person;
|
||||
expect(betaPerson1!.person.name).toBe(name);
|
||||
|
@ -167,13 +164,12 @@ test("Create user with accept-language", async () => {
|
|||
});
|
||||
let user = await registerUser(lemmy_http, alphaUrl);
|
||||
|
||||
let my_user = await getMyUser(user);
|
||||
expect(my_user).toBeDefined();
|
||||
expect(my_user?.local_user_view.local_user.interface_language).toBe("fr");
|
||||
let site = await getSite(user);
|
||||
expect(site.my_user).toBeDefined();
|
||||
expect(site.my_user?.local_user_view.local_user.interface_language).toBe(
|
||||
"fr",
|
||||
);
|
||||
let langs = site.all_languages
|
||||
.filter(a => site.my_user?.discussion_languages.includes(a.id))
|
||||
.filter(a => my_user.discussion_languages.includes(a.id))
|
||||
.map(l => l.code);
|
||||
// should have languages from accept header, as well as "undetermined"
|
||||
// which is automatically enabled by backend
|
||||
|
@ -219,8 +215,8 @@ test("Set a new avatar, old avatar is deleted", async () => {
|
|||
// Now try to save a user settings, with the icon missing,
|
||||
// and make sure it doesn't clear the data, or delete the image
|
||||
await saveUserSettingsBio(alpha);
|
||||
let site = await getSite(alpha);
|
||||
expect(site.my_user?.local_user_view.person.avatar).toBe(upload2.url);
|
||||
let my_user = await getMyUser(alpha);
|
||||
expect(my_user.local_user_view.person.avatar).toBe(upload2.url);
|
||||
|
||||
// make sure only the new avatar is kept
|
||||
const listMediaRes4 = await alphaImage.listMedia();
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
# or
|
||||
|
||||
# If enabled, all images from remote domains are rewritten to pass through
|
||||
# `/api/v3/image_proxy`, including embedded images in markdown. Images are stored temporarily
|
||||
# `/api/v4/image_proxy`, including embedded images in markdown. Images are stored temporarily
|
||||
# in pict-rs for caching. This improves privacy as users don't expose their IP to untrusted
|
||||
# servers, and decreases load on other servers. However it increases bandwidth use for the
|
||||
# local server.
|
||||
|
|
|
@ -17,7 +17,7 @@ use lemmy_db_views_actor::structs::CommunityView;
|
|||
use lemmy_utils::error::{LemmyErrorExt, LemmyErrorType, LemmyResult};
|
||||
|
||||
#[tracing::instrument(skip(context))]
|
||||
pub async fn block_community(
|
||||
pub async fn user_block_community(
|
||||
data: Json<BlockCommunity>,
|
||||
context: Data<LemmyContext>,
|
||||
local_user_view: LocalUserView,
|
||||
|
|
|
@ -12,7 +12,7 @@ use lemmy_db_views_actor::structs::PersonView;
|
|||
use lemmy_utils::error::{LemmyErrorExt, LemmyErrorType, LemmyResult};
|
||||
|
||||
#[tracing::instrument(skip(context))]
|
||||
pub async fn block_person(
|
||||
pub async fn user_block_person(
|
||||
data: Json<BlockPerson>,
|
||||
context: Data<LemmyContext>,
|
||||
local_user_view: LocalUserView,
|
||||
|
|
|
@ -15,5 +15,6 @@ pub mod report_count;
|
|||
pub mod reset_password;
|
||||
pub mod save_settings;
|
||||
pub mod update_totp;
|
||||
pub mod user_block_instance;
|
||||
pub mod validate_auth;
|
||||
pub mod verify_email;
|
||||
|
|
|
@ -69,14 +69,12 @@ pub async fn leave_admin(
|
|||
site_view,
|
||||
admins,
|
||||
version: VERSION.to_string(),
|
||||
my_user: None,
|
||||
all_languages,
|
||||
discussion_languages,
|
||||
oauth_providers: Some(oauth_providers),
|
||||
admin_oauth_providers: None,
|
||||
blocked_urls,
|
||||
tagline,
|
||||
taglines: vec![],
|
||||
custom_emojis: vec![],
|
||||
my_user: None,
|
||||
}))
|
||||
}
|
||||
|
|
|
@ -6,4 +6,3 @@ pub mod list_all_media;
|
|||
pub mod mod_log;
|
||||
pub mod purge;
|
||||
pub mod registration_applications;
|
||||
pub mod user_block_instance;
|
||||
|
|
|
@ -11,7 +11,7 @@ Here is an example using [reqwest](https://crates.io/crates/reqwest):
|
|||
};
|
||||
let client = Client::new();
|
||||
let response = client
|
||||
.get("https://lemmy.ml/api/v3/post/list")
|
||||
.get("https://lemmy.ml/api/v4/post/list")
|
||||
.query(¶ms)
|
||||
.send()
|
||||
.await?;
|
||||
|
|
|
@ -429,7 +429,7 @@ pub struct EditSite {
|
|||
/// The response for a site.
|
||||
pub struct SiteResponse {
|
||||
pub site_view: SiteView,
|
||||
/// deprecated, use field `tagline` or /api/v3/tagline/list
|
||||
/// deprecated, use field `tagline` or /api/v4/tagline/list
|
||||
pub taglines: Vec<()>,
|
||||
}
|
||||
|
||||
|
@ -442,14 +442,10 @@ pub struct GetSiteResponse {
|
|||
pub site_view: SiteView,
|
||||
pub admins: Vec<PersonView>,
|
||||
pub version: String,
|
||||
#[cfg_attr(feature = "full", ts(optional))]
|
||||
#[cfg_attr(feature = "full", ts(skip))]
|
||||
pub my_user: Option<MyUserInfo>,
|
||||
pub all_languages: Vec<Language>,
|
||||
pub discussion_languages: Vec<LanguageId>,
|
||||
/// deprecated, use field `tagline` or /api/v3/tagline/list
|
||||
pub taglines: Vec<()>,
|
||||
/// deprecated, use /api/v3/custom_emoji/list
|
||||
pub custom_emojis: Vec<()>,
|
||||
/// If the site has any taglines, a random one is included here for displaying
|
||||
#[cfg_attr(feature = "full", ts(optional))]
|
||||
pub tagline: Option<Tagline>,
|
||||
|
|
|
@ -1125,7 +1125,7 @@ async fn proxy_image_link_internal(
|
|||
}
|
||||
}
|
||||
|
||||
/// Rewrite a link to go through `/api/v3/image_proxy` endpoint. This is only for remote urls and
|
||||
/// Rewrite a link to go through `/api/v4/image_proxy` endpoint. This is only for remote urls and
|
||||
/// if image_proxy setting is enabled.
|
||||
pub async fn proxy_image_link(link: Url, context: &LemmyContext) -> LemmyResult<DbUrl> {
|
||||
proxy_image_link_internal(
|
||||
|
@ -1177,7 +1177,7 @@ fn build_proxied_image_url(
|
|||
protocol_and_hostname: &str,
|
||||
) -> Result<Url, url::ParseError> {
|
||||
Url::parse(&format!(
|
||||
"{}/api/v3/image_proxy?url={}",
|
||||
"{}/api/v4/image_proxy?url={}",
|
||||
protocol_and_hostname,
|
||||
encode(link.as_str())
|
||||
))
|
||||
|
@ -1256,7 +1256,7 @@ mod tests {
|
|||
)
|
||||
.await?;
|
||||
assert_eq!(
|
||||
"https://lemmy-alpha/api/v3/image_proxy?url=http%3A%2F%2Flemmy-beta%2Fimage.png",
|
||||
"https://lemmy-alpha/api/v4/image_proxy?url=http%3A%2F%2Flemmy-beta%2Fimage.png",
|
||||
proxied.as_str()
|
||||
);
|
||||
|
||||
|
|
|
@ -1,30 +1,32 @@
|
|||
use crate::user::my_user::get_my_user;
|
||||
use actix_web::web::{Data, Json};
|
||||
use lemmy_api_common::{
|
||||
context::LemmyContext,
|
||||
site::{GetSiteResponse, MyUserInfo},
|
||||
};
|
||||
use lemmy_api_common::{context::LemmyContext, site::GetSiteResponse};
|
||||
use lemmy_db_schema::source::{
|
||||
actor_language::{LocalUserLanguage, SiteLanguage},
|
||||
community_block::CommunityBlock,
|
||||
instance_block::InstanceBlock,
|
||||
actor_language::SiteLanguage,
|
||||
language::Language,
|
||||
local_site_url_blocklist::LocalSiteUrlBlocklist,
|
||||
oauth_provider::OAuthProvider,
|
||||
person_block::PersonBlock,
|
||||
tagline::Tagline,
|
||||
};
|
||||
use lemmy_db_views::structs::{LocalUserView, SiteView};
|
||||
use lemmy_db_views_actor::structs::{CommunityFollowerView, CommunityModeratorView, PersonView};
|
||||
use lemmy_utils::{
|
||||
build_cache,
|
||||
error::{LemmyErrorExt, LemmyErrorType, LemmyResult},
|
||||
CacheLock,
|
||||
VERSION,
|
||||
};
|
||||
use lemmy_db_views_actor::structs::PersonView;
|
||||
use lemmy_utils::{build_cache, error::LemmyResult, CacheLock, VERSION};
|
||||
use std::sync::LazyLock;
|
||||
|
||||
#[tracing::instrument(skip(context))]
|
||||
pub async fn get_site(
|
||||
pub async fn get_site_v3(
|
||||
local_user_view: Option<LocalUserView>,
|
||||
context: Data<LemmyContext>,
|
||||
) -> LemmyResult<Json<GetSiteResponse>> {
|
||||
let mut site = get_site_v4(local_user_view.clone(), context.clone()).await?;
|
||||
if let Some(local_user_view) = local_user_view {
|
||||
site.my_user = Some(get_my_user(local_user_view, context).await?.0);
|
||||
}
|
||||
Ok(site)
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(context))]
|
||||
pub async fn get_site_v4(
|
||||
local_user_view: Option<LocalUserView>,
|
||||
context: Data<LemmyContext>,
|
||||
) -> LemmyResult<Json<GetSiteResponse>> {
|
||||
|
@ -35,42 +37,6 @@ pub async fn get_site(
|
|||
.await
|
||||
.map_err(|e| anyhow::anyhow!("Failed to construct site response: {e}"))?;
|
||||
|
||||
// Build the local user with parallel queries and add it to site response
|
||||
site_response.my_user = if let Some(ref local_user_view) = local_user_view {
|
||||
let person_id = local_user_view.person.id;
|
||||
let local_user_id = local_user_view.local_user.id;
|
||||
let pool = &mut context.pool();
|
||||
|
||||
let (
|
||||
follows,
|
||||
community_blocks,
|
||||
instance_blocks,
|
||||
person_blocks,
|
||||
moderates,
|
||||
discussion_languages,
|
||||
) = lemmy_db_schema::try_join_with_pool!(pool => (
|
||||
|pool| CommunityFollowerView::for_person(pool, person_id),
|
||||
|pool| CommunityBlock::for_person(pool, person_id),
|
||||
|pool| InstanceBlock::for_person(pool, person_id),
|
||||
|pool| PersonBlock::for_person(pool, person_id),
|
||||
|pool| CommunityModeratorView::for_person(pool, person_id, Some(&local_user_view.local_user)),
|
||||
|pool| LocalUserLanguage::read(pool, local_user_id)
|
||||
))
|
||||
.with_lemmy_type(LemmyErrorType::SystemErrLogin)?;
|
||||
|
||||
Some(MyUserInfo {
|
||||
local_user_view: local_user_view.clone(),
|
||||
follows,
|
||||
moderates,
|
||||
community_blocks,
|
||||
instance_blocks,
|
||||
person_blocks,
|
||||
discussion_languages,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
// filter oauth_providers for public access
|
||||
if !local_user_view
|
||||
.map(|l| l.local_user.admin)
|
||||
|
@ -103,7 +69,5 @@ async fn read_site(context: &LemmyContext) -> LemmyResult<GetSiteResponse> {
|
|||
tagline,
|
||||
oauth_providers: Some(oauth_providers),
|
||||
admin_oauth_providers: Some(admin_oauth_providers),
|
||||
taglines: vec![],
|
||||
custom_emojis: vec![],
|
||||
})
|
||||
}
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
pub mod create;
|
||||
pub mod delete;
|
||||
pub mod my_user;
|
||||
|
|
43
crates/api_crud/src/user/my_user.rs
Normal file
43
crates/api_crud/src/user/my_user.rs
Normal file
|
@ -0,0 +1,43 @@
|
|||
use actix_web::web::{Data, Json};
|
||||
use lemmy_api_common::{context::LemmyContext, site::MyUserInfo};
|
||||
use lemmy_db_schema::source::{
|
||||
actor_language::LocalUserLanguage,
|
||||
community_block::CommunityBlock,
|
||||
instance_block::InstanceBlock,
|
||||
person_block::PersonBlock,
|
||||
};
|
||||
use lemmy_db_views::structs::LocalUserView;
|
||||
use lemmy_db_views_actor::structs::{CommunityFollowerView, CommunityModeratorView};
|
||||
use lemmy_utils::error::{LemmyErrorExt, LemmyErrorType, LemmyResult};
|
||||
|
||||
#[tracing::instrument(skip(context))]
|
||||
pub async fn get_my_user(
|
||||
local_user_view: LocalUserView,
|
||||
context: Data<LemmyContext>,
|
||||
) -> LemmyResult<Json<MyUserInfo>> {
|
||||
// Build the local user with parallel queries and add it to site response
|
||||
let person_id = local_user_view.person.id;
|
||||
let local_user_id = local_user_view.local_user.id;
|
||||
let pool = &mut context.pool();
|
||||
|
||||
let (follows, community_blocks, instance_blocks, person_blocks, moderates, discussion_languages) =
|
||||
lemmy_db_schema::try_join_with_pool!(pool => (
|
||||
|pool| CommunityFollowerView::for_person(pool, person_id),
|
||||
|pool| CommunityBlock::for_person(pool, person_id),
|
||||
|pool| InstanceBlock::for_person(pool, person_id),
|
||||
|pool| PersonBlock::for_person(pool, person_id),
|
||||
|pool| CommunityModeratorView::for_person(pool, person_id, Some(&local_user_view.local_user)),
|
||||
|pool| LocalUserLanguage::read(pool, local_user_id)
|
||||
))
|
||||
.with_lemmy_type(LemmyErrorType::SystemErrLogin)?;
|
||||
|
||||
Ok(Json(MyUserInfo {
|
||||
local_user_view: local_user_view.clone(),
|
||||
follows,
|
||||
moderates,
|
||||
community_blocks,
|
||||
instance_blocks,
|
||||
person_blocks,
|
||||
discussion_languages,
|
||||
}))
|
||||
}
|
|
@ -120,7 +120,7 @@ pub enum PictrsImageMode {
|
|||
#[default]
|
||||
StoreLinkPreviews,
|
||||
/// If enabled, all images from remote domains are rewritten to pass through
|
||||
/// `/api/v3/image_proxy`, including embedded images in markdown. Images are stored temporarily
|
||||
/// `/api/v4/image_proxy`, including embedded images in markdown. Images are stored temporarily
|
||||
/// in pict-rs for caching. This improves privacy as users don't expose their IP to untrusted
|
||||
/// servers, and decreases load on other servers. However it increases bandwidth use for the
|
||||
/// local server.
|
||||
|
|
|
@ -4,7 +4,7 @@ use markdown_it::{plugins::cmark::inline::image::Image, NodeValue};
|
|||
use url::Url;
|
||||
use urlencoding::encode;
|
||||
|
||||
/// Rewrites all links to remote domains in markdown, so they go through `/api/v3/image_proxy`.
|
||||
/// Rewrites all links to remote domains in markdown, so they go through `/api/v4/image_proxy`.
|
||||
pub fn markdown_rewrite_image_links(mut src: String) -> (String, Vec<Url>) {
|
||||
let links_offsets = find_urls::<Image>(&src);
|
||||
|
||||
|
@ -18,7 +18,7 @@ pub fn markdown_rewrite_image_links(mut src: String) -> (String, Vec<Url>) {
|
|||
// If link points to remote domain, replace with proxied link
|
||||
if parsed.domain() != Some(&SETTINGS.hostname) {
|
||||
let mut proxied = format!(
|
||||
"{}/api/v3/image_proxy?url={}",
|
||||
"{}/api/v4/image_proxy?url={}",
|
||||
SETTINGS.get_protocol_and_hostname(),
|
||||
encode(url),
|
||||
);
|
||||
|
@ -115,7 +115,7 @@ mod tests {
|
|||
(
|
||||
"remote image proxied",
|
||||
"![link](http://example.com/image.jpg)",
|
||||
"![link](https://lemmy-alpha/api/v3/image_proxy?url=http%3A%2F%2Fexample.com%2Fimage.jpg)",
|
||||
"![link](https://lemmy-alpha/api/v4/image_proxy?url=http%3A%2F%2Fexample.com%2Fimage.jpg)",
|
||||
),
|
||||
(
|
||||
"local image unproxied",
|
||||
|
@ -125,7 +125,7 @@ mod tests {
|
|||
(
|
||||
"multiple image links",
|
||||
"![link](http://example.com/image1.jpg) ![link](http://example.com/image2.jpg)",
|
||||
"![link](https://lemmy-alpha/api/v3/image_proxy?url=http%3A%2F%2Fexample.com%2Fimage1.jpg) ![link](https://lemmy-alpha/api/v3/image_proxy?url=http%3A%2F%2Fexample.com%2Fimage2.jpg)",
|
||||
"![link](https://lemmy-alpha/api/v4/image_proxy?url=http%3A%2F%2Fexample.com%2Fimage1.jpg) ![link](https://lemmy-alpha/api/v4/image_proxy?url=http%3A%2F%2Fexample.com%2Fimage2.jpg)",
|
||||
),
|
||||
(
|
||||
"empty link handled",
|
||||
|
@ -135,7 +135,7 @@ mod tests {
|
|||
(
|
||||
"empty label handled",
|
||||
"![](http://example.com/image.jpg)",
|
||||
"![](https://lemmy-alpha/api/v3/image_proxy?url=http%3A%2F%2Fexample.com%2Fimage.jpg)"
|
||||
"![](https://lemmy-alpha/api/v4/image_proxy?url=http%3A%2F%2Fexample.com%2Fimage.jpg)"
|
||||
),
|
||||
(
|
||||
"invalid image link removed",
|
||||
|
@ -145,12 +145,12 @@ mod tests {
|
|||
(
|
||||
"label with nested markdown handled",
|
||||
"![a *b* c](http://example.com/image.jpg)",
|
||||
"![a *b* c](https://lemmy-alpha/api/v3/image_proxy?url=http%3A%2F%2Fexample.com%2Fimage.jpg)"
|
||||
"![a *b* c](https://lemmy-alpha/api/v4/image_proxy?url=http%3A%2F%2Fexample.com%2Fimage.jpg)"
|
||||
),
|
||||
(
|
||||
"custom emoji support",
|
||||
r#"![party-blob](https://www.hexbear.net/pictrs/image/83405746-0620-4728-9358-5f51b040ffee.gif "emoji party-blob")"#,
|
||||
r#"![party-blob](https://lemmy-alpha/api/v3/image_proxy?url=https%3A%2F%2Fwww.hexbear.net%2Fpictrs%2Fimage%2F83405746-0620-4728-9358-5f51b040ffee.gif "emoji party-blob")"#
|
||||
r#"![party-blob](https://lemmy-alpha/api/v4/image_proxy?url=https%3A%2F%2Fwww.hexbear.net%2Fpictrs%2Fimage%2F83405746-0620-4728-9358-5f51b040ffee.gif "emoji party-blob")"#
|
||||
)
|
||||
];
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ mod tests {
|
|||
(
|
||||
"remote image proxied",
|
||||
"![link](http://example.com/image.jpg)",
|
||||
"![link](https://lemmy-alpha/api/v3/image_proxy?url=http%3A%2F%2Fexample.com%2Fimage.jpg)",
|
||||
"![link](https://lemmy-alpha/api/v4/image_proxy?url=http%3A%2F%2Fexample.com%2Fimage.jpg)",
|
||||
),
|
||||
(
|
||||
"local image unproxied",
|
||||
|
@ -151,7 +151,7 @@ mod tests {
|
|||
(
|
||||
"multiple image links",
|
||||
"![link](http://example.com/image1.jpg) ![link](http://example.com/image2.jpg)",
|
||||
"![link](https://lemmy-alpha/api/v3/image_proxy?url=http%3A%2F%2Fexample.com%2Fimage1.jpg) ![link](https://lemmy-alpha/api/v3/image_proxy?url=http%3A%2F%2Fexample.com%2Fimage2.jpg)",
|
||||
"![link](https://lemmy-alpha/api/v4/image_proxy?url=http%3A%2F%2Fexample.com%2Fimage1.jpg) ![link](https://lemmy-alpha/api/v4/image_proxy?url=http%3A%2F%2Fexample.com%2Fimage2.jpg)",
|
||||
),
|
||||
(
|
||||
"empty link handled",
|
||||
|
@ -161,7 +161,7 @@ mod tests {
|
|||
(
|
||||
"empty label handled",
|
||||
"![](http://example.com/image.jpg)",
|
||||
"![](https://lemmy-alpha/api/v3/image_proxy?url=http%3A%2F%2Fexample.com%2Fimage.jpg)"
|
||||
"![](https://lemmy-alpha/api/v4/image_proxy?url=http%3A%2F%2Fexample.com%2Fimage.jpg)"
|
||||
),
|
||||
(
|
||||
"invalid image link removed",
|
||||
|
@ -171,12 +171,12 @@ mod tests {
|
|||
(
|
||||
"label with nested markdown handled",
|
||||
"![a *b* c](http://example.com/image.jpg)",
|
||||
"![a *b* c](https://lemmy-alpha/api/v3/image_proxy?url=http%3A%2F%2Fexample.com%2Fimage.jpg)"
|
||||
"![a *b* c](https://lemmy-alpha/api/v4/image_proxy?url=http%3A%2F%2Fexample.com%2Fimage.jpg)"
|
||||
),
|
||||
(
|
||||
"custom emoji support",
|
||||
r#"![party-blob](https://www.hexbear.net/pictrs/image/83405746-0620-4728-9358-5f51b040ffee.gif "emoji party-blob")"#,
|
||||
r#"![party-blob](https://lemmy-alpha/api/v3/image_proxy?url=https%3A%2F%2Fwww.hexbear.net%2Fpictrs%2Fimage%2F83405746-0620-4728-9358-5f51b040ffee.gif "emoji party-blob")"#
|
||||
r#"![party-blob](https://lemmy-alpha/api/v4/image_proxy?url=https%3A%2F%2Fwww.hexbear.net%2Fpictrs%2Fimage%2F83405746-0620-4728-9358-5f51b040ffee.gif "emoji party-blob")"#
|
||||
)
|
||||
];
|
||||
|
||||
|
|
|
@ -14,21 +14,15 @@ use lemmy_api::{
|
|||
community::{
|
||||
add_mod::add_mod_to_community,
|
||||
ban::ban_from_community,
|
||||
block::block_community,
|
||||
block::user_block_community,
|
||||
follow::follow_community,
|
||||
hide::hide_community,
|
||||
pending_follows::{
|
||||
approve::post_pending_follows_approve,
|
||||
count::get_pending_follows_count,
|
||||
list::get_pending_follows_list,
|
||||
},
|
||||
random::get_random_community,
|
||||
transfer::transfer_community,
|
||||
},
|
||||
local_user::{
|
||||
add_admin::add_admin,
|
||||
ban_person::ban_from_site,
|
||||
block::block_person,
|
||||
block::user_block_person,
|
||||
change_password::change_password,
|
||||
change_password_after_reset::change_password_after_reset,
|
||||
generate_totp_secret::generate_totp_secret,
|
||||
|
@ -50,6 +44,7 @@ use lemmy_api::{
|
|||
reset_password::reset_password,
|
||||
save_settings::save_user_settings,
|
||||
update_totp::update_totp,
|
||||
user_block_instance::user_block_instance,
|
||||
validate_auth::validate_auth,
|
||||
verify_email::verify_email,
|
||||
},
|
||||
|
@ -60,7 +55,6 @@ use lemmy_api::{
|
|||
like::like_post,
|
||||
list_post_likes::list_post_likes,
|
||||
lock::lock_post,
|
||||
mark_many_read::mark_posts_as_read,
|
||||
mark_read::mark_post_as_read,
|
||||
save::save_post,
|
||||
},
|
||||
|
@ -76,8 +70,6 @@ use lemmy_api::{
|
|||
resolve::resolve_pm_report,
|
||||
},
|
||||
site::{
|
||||
admin_allow_instance::admin_allow_instance,
|
||||
admin_block_instance::admin_block_instance,
|
||||
federated_instances::get_federated_instances,
|
||||
leave_admin::leave_admin,
|
||||
list_all_media::list_all_media,
|
||||
|
@ -94,7 +86,6 @@ use lemmy_api::{
|
|||
list::list_registration_applications,
|
||||
unread_count::get_unread_registration_application_count,
|
||||
},
|
||||
user_block_instance::user_block_instance,
|
||||
},
|
||||
sitemap::get_sitemap,
|
||||
};
|
||||
|
@ -116,14 +107,8 @@ use lemmy_api_crud::{
|
|||
custom_emoji::{
|
||||
create::create_custom_emoji,
|
||||
delete::delete_custom_emoji,
|
||||
list::list_custom_emojis,
|
||||
update::update_custom_emoji,
|
||||
},
|
||||
oauth_provider::{
|
||||
create::create_oauth_provider,
|
||||
delete::delete_oauth_provider,
|
||||
update::update_oauth_provider,
|
||||
},
|
||||
post::{
|
||||
create::create_post,
|
||||
delete::delete_post,
|
||||
|
@ -137,17 +122,8 @@ use lemmy_api_crud::{
|
|||
read::get_private_message,
|
||||
update::update_private_message,
|
||||
},
|
||||
site::{create::create_site, read::get_site, update::update_site},
|
||||
tagline::{
|
||||
create::create_tagline,
|
||||
delete::delete_tagline,
|
||||
list::list_taglines,
|
||||
update::update_tagline,
|
||||
},
|
||||
user::{
|
||||
create::{authenticate_with_oauth, register},
|
||||
delete::delete_account,
|
||||
},
|
||||
site::{create::create_site, read::get_site_v3, update::update_site},
|
||||
user::{create::register, delete::delete_account},
|
||||
};
|
||||
use lemmy_apub::api::{
|
||||
list_comments::list_comments,
|
||||
|
@ -161,6 +137,9 @@ use lemmy_apub::api::{
|
|||
use lemmy_routes::images::image_proxy;
|
||||
use lemmy_utils::rate_limit::RateLimitCell;
|
||||
|
||||
// Deprecated, use api v4 instead.
|
||||
// When removing api v3, we also need to rewrite all links in database with
|
||||
// `/api/v3/image_proxy` to use `/api/v4/image_proxy` instead.
|
||||
pub fn config(cfg: &mut ServiceConfig, rate_limit: &RateLimitCell) {
|
||||
cfg.service(
|
||||
scope("/api/v3")
|
||||
|
@ -169,7 +148,7 @@ pub fn config(cfg: &mut ServiceConfig, rate_limit: &RateLimitCell) {
|
|||
.service(
|
||||
scope("/site")
|
||||
.wrap(rate_limit.message())
|
||||
.route("", get().to(get_site))
|
||||
.route("", get().to(get_site_v3))
|
||||
// Admin Actions
|
||||
.route("", post().to(create_site))
|
||||
.route("", put().to(update_site))
|
||||
|
@ -202,24 +181,16 @@ pub fn config(cfg: &mut ServiceConfig, rate_limit: &RateLimitCell) {
|
|||
.wrap(rate_limit.message())
|
||||
.route("", get().to(get_community))
|
||||
.route("", put().to(update_community))
|
||||
.route("/random", get().to(get_random_community))
|
||||
.route("/hide", put().to(hide_community))
|
||||
.route("/list", get().to(list_communities))
|
||||
.route("/follow", post().to(follow_community))
|
||||
.route("/block", post().to(block_community))
|
||||
.route("/block", post().to(user_block_community))
|
||||
.route("/delete", post().to(delete_community))
|
||||
// Mod Actions
|
||||
.route("/remove", post().to(remove_community))
|
||||
.route("/transfer", post().to(transfer_community))
|
||||
.route("/ban_user", post().to(ban_from_community))
|
||||
.route("/mod", post().to(add_mod_to_community))
|
||||
.service(
|
||||
scope("/pending_follows")
|
||||
.wrap(rate_limit.message())
|
||||
.route("/count", get().to(get_pending_follows_count))
|
||||
.route("/list", get().to(get_pending_follows_list))
|
||||
.route("/approve", post().to(post_pending_follows_approve)),
|
||||
),
|
||||
.route("/mod", post().to(add_mod_to_community)),
|
||||
)
|
||||
.service(
|
||||
scope("/federated_instances")
|
||||
|
@ -242,7 +213,6 @@ pub fn config(cfg: &mut ServiceConfig, rate_limit: &RateLimitCell) {
|
|||
.route("/delete", post().to(delete_post))
|
||||
.route("/remove", post().to(remove_post))
|
||||
.route("/mark_as_read", post().to(mark_post_as_read))
|
||||
.route("/mark_many_as_read", post().to(mark_posts_as_read))
|
||||
.route("/hide", post().to(hide_post))
|
||||
.route("/lock", post().to(lock_post))
|
||||
.route("/feature", post().to(feature_post))
|
||||
|
@ -354,7 +324,7 @@ pub fn config(cfg: &mut ServiceConfig, rate_limit: &RateLimitCell) {
|
|||
// Admin action. I don't like that it's in /user
|
||||
.route("/ban", post().to(ban_from_site))
|
||||
.route("/banned", get().to(list_banned_users))
|
||||
.route("/block", post().to(block_person))
|
||||
.route("/block", post().to(user_block_person))
|
||||
// TODO Account actions. I don't like that they're in /user maybe /accounts
|
||||
.route("/logout", post().to(logout))
|
||||
.route("/delete_account", post().to(delete_account))
|
||||
|
@ -400,37 +370,14 @@ pub fn config(cfg: &mut ServiceConfig, rate_limit: &RateLimitCell) {
|
|||
.route("/community", post().to(purge_community))
|
||||
.route("/post", post().to(purge_post))
|
||||
.route("/comment", post().to(purge_comment)),
|
||||
)
|
||||
.service(
|
||||
scope("/tagline")
|
||||
.wrap(rate_limit.message())
|
||||
.route("", post().to(create_tagline))
|
||||
.route("", put().to(update_tagline))
|
||||
.route("/delete", post().to(delete_tagline))
|
||||
.route("/list", get().to(list_taglines)),
|
||||
)
|
||||
.route("block_instance", post().to(admin_block_instance))
|
||||
.route("allow_instance", post().to(admin_allow_instance)),
|
||||
),
|
||||
)
|
||||
.service(
|
||||
scope("/custom_emoji")
|
||||
.wrap(rate_limit.message())
|
||||
.route("", post().to(create_custom_emoji))
|
||||
.route("", put().to(update_custom_emoji))
|
||||
.route("/delete", post().to(delete_custom_emoji))
|
||||
.route("/list", get().to(list_custom_emojis)),
|
||||
)
|
||||
.service(
|
||||
scope("/oauth_provider")
|
||||
.wrap(rate_limit.message())
|
||||
.route("", post().to(create_oauth_provider))
|
||||
.route("", put().to(update_oauth_provider))
|
||||
.route("/delete", post().to(delete_oauth_provider)),
|
||||
)
|
||||
.service(
|
||||
scope("/oauth")
|
||||
.wrap(rate_limit.register())
|
||||
.route("/authenticate", post().to(authenticate_with_oauth)),
|
||||
.route("/delete", post().to(delete_custom_emoji)),
|
||||
),
|
||||
);
|
||||
cfg.service(
|
392
src/api_routes_v4.rs
Normal file
392
src/api_routes_v4.rs
Normal file
|
@ -0,0 +1,392 @@
|
|||
use actix_web::{guard, web::*};
|
||||
use lemmy_api::{
|
||||
comment::{
|
||||
distinguish::distinguish_comment,
|
||||
like::like_comment,
|
||||
list_comment_likes::list_comment_likes,
|
||||
save::save_comment,
|
||||
},
|
||||
comment_report::{
|
||||
create::create_comment_report,
|
||||
list::list_comment_reports,
|
||||
resolve::resolve_comment_report,
|
||||
},
|
||||
community::{
|
||||
add_mod::add_mod_to_community,
|
||||
ban::ban_from_community,
|
||||
block::user_block_community,
|
||||
follow::follow_community,
|
||||
hide::hide_community,
|
||||
pending_follows::{
|
||||
approve::post_pending_follows_approve,
|
||||
count::get_pending_follows_count,
|
||||
list::get_pending_follows_list,
|
||||
},
|
||||
random::get_random_community,
|
||||
transfer::transfer_community,
|
||||
},
|
||||
local_user::{
|
||||
add_admin::add_admin,
|
||||
ban_person::ban_from_site,
|
||||
block::user_block_person,
|
||||
change_password::change_password,
|
||||
change_password_after_reset::change_password_after_reset,
|
||||
generate_totp_secret::generate_totp_secret,
|
||||
get_captcha::get_captcha,
|
||||
list_banned::list_banned_users,
|
||||
list_logins::list_logins,
|
||||
list_media::list_media,
|
||||
login::login,
|
||||
logout::logout,
|
||||
notifications::{
|
||||
list_mentions::list_mentions,
|
||||
list_replies::list_replies,
|
||||
mark_all_read::mark_all_notifications_read,
|
||||
mark_mention_read::mark_person_mention_as_read,
|
||||
mark_reply_read::mark_reply_as_read,
|
||||
unread_count::unread_count,
|
||||
},
|
||||
report_count::report_count,
|
||||
reset_password::reset_password,
|
||||
save_settings::save_user_settings,
|
||||
update_totp::update_totp,
|
||||
user_block_instance::user_block_instance,
|
||||
validate_auth::validate_auth,
|
||||
verify_email::verify_email,
|
||||
},
|
||||
post::{
|
||||
feature::feature_post,
|
||||
get_link_metadata::get_link_metadata,
|
||||
hide::hide_post,
|
||||
like::like_post,
|
||||
list_post_likes::list_post_likes,
|
||||
lock::lock_post,
|
||||
mark_many_read::mark_posts_as_read,
|
||||
mark_read::mark_post_as_read,
|
||||
save::save_post,
|
||||
},
|
||||
post_report::{
|
||||
create::create_post_report,
|
||||
list::list_post_reports,
|
||||
resolve::resolve_post_report,
|
||||
},
|
||||
private_message::mark_read::mark_pm_as_read,
|
||||
private_message_report::{
|
||||
create::create_pm_report,
|
||||
list::list_pm_reports,
|
||||
resolve::resolve_pm_report,
|
||||
},
|
||||
site::{
|
||||
admin_allow_instance::admin_allow_instance,
|
||||
admin_block_instance::admin_block_instance,
|
||||
federated_instances::get_federated_instances,
|
||||
leave_admin::leave_admin,
|
||||
list_all_media::list_all_media,
|
||||
mod_log::get_mod_log,
|
||||
purge::{
|
||||
comment::purge_comment,
|
||||
community::purge_community,
|
||||
person::purge_person,
|
||||
post::purge_post,
|
||||
},
|
||||
registration_applications::{
|
||||
approve::approve_registration_application,
|
||||
get::get_registration_application,
|
||||
list::list_registration_applications,
|
||||
unread_count::get_unread_registration_application_count,
|
||||
},
|
||||
},
|
||||
sitemap::get_sitemap,
|
||||
};
|
||||
use lemmy_api_crud::{
|
||||
comment::{
|
||||
create::create_comment,
|
||||
delete::delete_comment,
|
||||
read::get_comment,
|
||||
remove::remove_comment,
|
||||
update::update_comment,
|
||||
},
|
||||
community::{
|
||||
create::create_community,
|
||||
delete::delete_community,
|
||||
list::list_communities,
|
||||
remove::remove_community,
|
||||
update::update_community,
|
||||
},
|
||||
custom_emoji::{
|
||||
create::create_custom_emoji,
|
||||
delete::delete_custom_emoji,
|
||||
list::list_custom_emojis,
|
||||
update::update_custom_emoji,
|
||||
},
|
||||
oauth_provider::{
|
||||
create::create_oauth_provider,
|
||||
delete::delete_oauth_provider,
|
||||
update::update_oauth_provider,
|
||||
},
|
||||
post::{
|
||||
create::create_post,
|
||||
delete::delete_post,
|
||||
read::get_post,
|
||||
remove::remove_post,
|
||||
update::update_post,
|
||||
},
|
||||
private_message::{
|
||||
create::create_private_message,
|
||||
delete::delete_private_message,
|
||||
read::get_private_message,
|
||||
update::update_private_message,
|
||||
},
|
||||
site::{create::create_site, read::get_site_v4, update::update_site},
|
||||
tagline::{
|
||||
create::create_tagline,
|
||||
delete::delete_tagline,
|
||||
list::list_taglines,
|
||||
update::update_tagline,
|
||||
},
|
||||
user::{
|
||||
create::{authenticate_with_oauth, register},
|
||||
delete::delete_account,
|
||||
my_user::get_my_user,
|
||||
},
|
||||
};
|
||||
use lemmy_apub::api::{
|
||||
list_comments::list_comments,
|
||||
list_posts::list_posts,
|
||||
read_community::get_community,
|
||||
read_person::read_person,
|
||||
resolve_object::resolve_object,
|
||||
search::search,
|
||||
user_settings_backup::{export_settings, import_settings},
|
||||
};
|
||||
use lemmy_routes::images::image_proxy;
|
||||
use lemmy_utils::rate_limit::RateLimitCell;
|
||||
|
||||
pub fn config(cfg: &mut ServiceConfig, rate_limit: &RateLimitCell) {
|
||||
cfg.service(
|
||||
scope("/api/v4")
|
||||
.wrap(rate_limit.message())
|
||||
.route("/image_proxy", get().to(image_proxy))
|
||||
// Site
|
||||
.service(
|
||||
scope("/site")
|
||||
.route("", get().to(get_site_v4))
|
||||
.route("", post().to(create_site))
|
||||
.route("", put().to(update_site)),
|
||||
)
|
||||
.route("/modlog", get().to(get_mod_log))
|
||||
.service(
|
||||
resource("/search")
|
||||
.wrap(rate_limit.search())
|
||||
.route(get().to(search)),
|
||||
)
|
||||
.route("/resolve_object", get().to(resolve_object))
|
||||
// Community
|
||||
.service(
|
||||
resource("/community")
|
||||
.guard(guard::Post())
|
||||
.wrap(rate_limit.register())
|
||||
.route(post().to(create_community)),
|
||||
)
|
||||
.service(
|
||||
scope("/community")
|
||||
.route("", get().to(get_community))
|
||||
.route("", put().to(update_community))
|
||||
.route("/random", get().to(get_random_community))
|
||||
.route("/hide", put().to(hide_community))
|
||||
.route("/list", get().to(list_communities))
|
||||
.route("/follow", post().to(follow_community))
|
||||
.route("/delete", post().to(delete_community))
|
||||
// Mod Actions
|
||||
.route("/remove", post().to(remove_community))
|
||||
.route("/transfer", post().to(transfer_community))
|
||||
.route("/ban_user", post().to(ban_from_community))
|
||||
.route("/mod", post().to(add_mod_to_community))
|
||||
.service(
|
||||
scope("/pending_follows")
|
||||
.route("/count", get().to(get_pending_follows_count))
|
||||
.route("/list", get().to(get_pending_follows_list))
|
||||
.route("/approve", post().to(post_pending_follows_approve)),
|
||||
),
|
||||
)
|
||||
.route("/federated_instances", get().to(get_federated_instances))
|
||||
// Post
|
||||
.service(
|
||||
// Handle POST to /post separately to add the post() rate limitter
|
||||
resource("/post")
|
||||
.guard(guard::Post())
|
||||
.wrap(rate_limit.post())
|
||||
.route(post().to(create_post)),
|
||||
)
|
||||
.service(
|
||||
scope("/post")
|
||||
.route("", get().to(get_post))
|
||||
.route("", put().to(update_post))
|
||||
.route("/delete", post().to(delete_post))
|
||||
.route("/remove", post().to(remove_post))
|
||||
.route("/mark_as_read", post().to(mark_post_as_read))
|
||||
.route("/mark_as_read/many", post().to(mark_posts_as_read))
|
||||
.route("/hide", post().to(hide_post))
|
||||
.route("/lock", post().to(lock_post))
|
||||
.route("/feature", post().to(feature_post))
|
||||
.route("/list", get().to(list_posts))
|
||||
.route("/like", post().to(like_post))
|
||||
.route("/like/list", get().to(list_post_likes))
|
||||
.route("/save", put().to(save_post))
|
||||
.route("/report", post().to(create_post_report))
|
||||
.route("/report/resolve", put().to(resolve_post_report))
|
||||
.route("/report/list", get().to(list_post_reports))
|
||||
.route("/site_metadata", get().to(get_link_metadata)),
|
||||
)
|
||||
// Comment
|
||||
.service(
|
||||
// Handle POST to /comment separately to add the comment() rate limitter
|
||||
resource("/comment")
|
||||
.guard(guard::Post())
|
||||
.wrap(rate_limit.comment())
|
||||
.route(post().to(create_comment)),
|
||||
)
|
||||
.service(
|
||||
scope("/comment")
|
||||
.route("", get().to(get_comment))
|
||||
.route("", put().to(update_comment))
|
||||
.route("/delete", post().to(delete_comment))
|
||||
.route("/remove", post().to(remove_comment))
|
||||
.route("/mark_as_read", post().to(mark_reply_as_read))
|
||||
.route("/distinguish", post().to(distinguish_comment))
|
||||
.route("/like", post().to(like_comment))
|
||||
.route("/like/list", get().to(list_comment_likes))
|
||||
.route("/save", put().to(save_comment))
|
||||
.route("/list", get().to(list_comments))
|
||||
.route("/report", post().to(create_comment_report))
|
||||
.route("/report/resolve", put().to(resolve_comment_report))
|
||||
.route("/report/list", get().to(list_comment_reports)),
|
||||
)
|
||||
// Private Message
|
||||
.service(
|
||||
scope("/private_message")
|
||||
.route("/list", get().to(get_private_message))
|
||||
.route("", post().to(create_private_message))
|
||||
.route("", put().to(update_private_message))
|
||||
.route("/delete", post().to(delete_private_message))
|
||||
.route("/mark_as_read", post().to(mark_pm_as_read))
|
||||
.route("/report", post().to(create_pm_report))
|
||||
.route("/report/resolve", put().to(resolve_pm_report))
|
||||
.route("/report/list", get().to(list_pm_reports)),
|
||||
)
|
||||
// User
|
||||
.service(
|
||||
scope("/account/auth")
|
||||
.guard(guard::Post())
|
||||
.wrap(rate_limit.register())
|
||||
.route("/register", post().to(register))
|
||||
.route("/login", post().to(login))
|
||||
.route("/logout", post().to(logout))
|
||||
.route("/password_reset", post().to(reset_password))
|
||||
.route("/get_captcha", get().to(get_captcha))
|
||||
.route("/password_change", post().to(change_password_after_reset))
|
||||
.route("/change_password", put().to(change_password))
|
||||
.route("/totp/generate", post().to(generate_totp_secret))
|
||||
.route("/totp/update", post().to(update_totp))
|
||||
.route("/verify_email", post().to(verify_email)),
|
||||
)
|
||||
.route("/account/settings/save", put().to(save_user_settings))
|
||||
.service(
|
||||
scope("/account/settings")
|
||||
.wrap(rate_limit.import_user_settings())
|
||||
.route("/export", get().to(export_settings))
|
||||
.route("/import", post().to(import_settings)),
|
||||
)
|
||||
.service(
|
||||
scope("/account")
|
||||
.route("", get().to(get_my_user))
|
||||
.route("/list_media", get().to(list_media))
|
||||
.route("/mention", get().to(list_mentions))
|
||||
.route("/replies", get().to(list_replies))
|
||||
.route("/delete", post().to(delete_account))
|
||||
.route(
|
||||
"/mention/mark_as_read",
|
||||
post().to(mark_person_mention_as_read),
|
||||
)
|
||||
.route(
|
||||
"/mention/mark_as_read/all",
|
||||
post().to(mark_all_notifications_read),
|
||||
)
|
||||
.route("/report_count", get().to(report_count))
|
||||
.route("/unread_count", get().to(unread_count))
|
||||
.route("/list_logins", get().to(list_logins))
|
||||
.route("/validate_auth", get().to(validate_auth))
|
||||
.service(
|
||||
scope("/block")
|
||||
.route("/person", post().to(user_block_person))
|
||||
.route("/community", post().to(user_block_community))
|
||||
.route("/instance", post().to(user_block_instance)),
|
||||
),
|
||||
)
|
||||
// User actions
|
||||
.route("/person", get().to(read_person))
|
||||
// Admin Actions
|
||||
.service(
|
||||
scope("/admin")
|
||||
.route("/add", post().to(add_admin))
|
||||
.route(
|
||||
"/registration_application/count",
|
||||
get().to(get_unread_registration_application_count),
|
||||
)
|
||||
.route(
|
||||
"/registration_application/list",
|
||||
get().to(list_registration_applications),
|
||||
)
|
||||
.route(
|
||||
"/registration_application/approve",
|
||||
put().to(approve_registration_application),
|
||||
)
|
||||
.route(
|
||||
"/registration_application",
|
||||
get().to(get_registration_application),
|
||||
)
|
||||
.route("/list_all_media", get().to(list_all_media))
|
||||
.service(
|
||||
scope("/purge")
|
||||
.route("/person", post().to(purge_person))
|
||||
.route("/community", post().to(purge_community))
|
||||
.route("/post", post().to(purge_post))
|
||||
.route("/comment", post().to(purge_comment)),
|
||||
)
|
||||
.service(
|
||||
scope("/tagline")
|
||||
.route("", post().to(create_tagline))
|
||||
.route("", put().to(update_tagline))
|
||||
.route("/delete", post().to(delete_tagline))
|
||||
.route("/list", get().to(list_taglines)),
|
||||
)
|
||||
.route("/ban", post().to(ban_from_site))
|
||||
.route("/banned", get().to(list_banned_users))
|
||||
.route("/leave", post().to(leave_admin))
|
||||
.service(
|
||||
scope("/instance")
|
||||
.route("/block", post().to(admin_block_instance))
|
||||
.route("/allow", post().to(admin_allow_instance)),
|
||||
),
|
||||
)
|
||||
.service(
|
||||
scope("/custom_emoji")
|
||||
.route("", post().to(create_custom_emoji))
|
||||
.route("", put().to(update_custom_emoji))
|
||||
.route("/delete", post().to(delete_custom_emoji))
|
||||
.route("/list", get().to(list_custom_emojis)),
|
||||
)
|
||||
.service(
|
||||
scope("/oauth_provider")
|
||||
.route("", post().to(create_oauth_provider))
|
||||
.route("", put().to(update_oauth_provider))
|
||||
.route("/delete", post().to(delete_oauth_provider)),
|
||||
)
|
||||
.service(
|
||||
scope("/oauth")
|
||||
.wrap(rate_limit.register())
|
||||
.route("/authenticate", post().to(authenticate_with_oauth)),
|
||||
)
|
||||
.route("/sitemap.xml", get().to(get_sitemap)),
|
||||
);
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
pub mod api_routes_http;
|
||||
pub mod api_routes_v3;
|
||||
pub mod api_routes_v4;
|
||||
pub mod code_migrations;
|
||||
pub mod prometheus_metrics;
|
||||
pub mod scheduled_tasks;
|
||||
|
@ -318,7 +319,8 @@ fn create_http_server(
|
|||
|
||||
// The routes
|
||||
app
|
||||
.configure(|cfg| api_routes_http::config(cfg, &rate_limit_cell))
|
||||
.configure(|cfg| api_routes_v3::config(cfg, &rate_limit_cell))
|
||||
.configure(|cfg| api_routes_v4::config(cfg, &rate_limit_cell))
|
||||
.configure(|cfg| {
|
||||
if federation_enabled {
|
||||
lemmy_apub::http::routes::config(cfg);
|
||||
|
|
Loading…
Reference in a new issue