Move lemmyClient generation into fetchInitialData functions. Fixes #2243 (#2260)

* Trying more ssr fixes. #2243

* Try to enforce cross-fetch again.

* Try to forward cookies.

* Try to forward cookies 2.

* Trying a new cross-fetch.

* Fixing headers

* Fixing some auth issues.

* Fixing isBanned.

* Fix shutdown.

* Pushing up some tries.

* Moving lemmyclient building into fetchInitialData functions.
This commit is contained in:
Dessalines 2023-12-04 22:07:36 -05:00 committed by GitHub
parent 03fcaa0815
commit 7702c041e5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 158 additions and 68 deletions

View file

@ -1,7 +1,6 @@
import { initializeSite, isAuthPath } from "@utils/app"; import { initializeSite, isAuthPath } from "@utils/app";
import { getHttpBaseInternal } from "@utils/env"; import { getHttpBaseInternal } from "@utils/env";
import { ErrorPageData } from "@utils/types"; import { ErrorPageData } from "@utils/types";
import * as cookie from "cookie";
import type { Request, Response } from "express"; import type { Request, Response } from "express";
import { StaticRouter, matchPath } from "inferno-router"; import { StaticRouter, matchPath } from "inferno-router";
import { renderToString } from "inferno-server"; import { renderToString } from "inferno-server";
@ -20,26 +19,19 @@ import {
import { createSsrHtml } from "../utils/create-ssr-html"; import { createSsrHtml } from "../utils/create-ssr-html";
import { getErrorPageData } from "../utils/get-error-page-data"; import { getErrorPageData } from "../utils/get-error-page-data";
import { setForwardedHeaders } from "../utils/set-forwarded-headers"; import { setForwardedHeaders } from "../utils/set-forwarded-headers";
import { authCookieName } from "../../shared/config"; import { getJwtCookie } from "../utils/has-jwt-cookie";
export default async (req: Request, res: Response) => { export default async (req: Request, res: Response) => {
try { try {
const activeRoute = routes.find(route => matchPath(req.path, route)); const activeRoute = routes.find(route => matchPath(req.path, route));
const headers = setForwardedHeaders(req.headers); const headers = setForwardedHeaders(req.headers);
const auth = getJwtCookie(req.headers);
const client = wrapClient( const client = wrapClient(
new LemmyHttp(getHttpBaseInternal(), { headers }), new LemmyHttp(getHttpBaseInternal(), { headers }),
); );
const auth = req.headers.cookie
? cookie.parse(req.headers.cookie)[authCookieName]
: undefined;
if (auth) {
headers["Authorization"] = `Bearer ${auth}`;
client.rawClient.setHeaders(headers);
}
const { path, url, query } = req; const { path, url, query } = req;
// Get site data first // Get site data first
@ -75,10 +67,10 @@ export default async (req: Request, res: Response) => {
if (site && activeRoute?.fetchInitialData) { if (site && activeRoute?.fetchInitialData) {
const initialFetchReq: InitialFetchRequest = { const initialFetchReq: InitialFetchRequest = {
client,
path, path,
query, query,
site, site,
headers,
}; };
routeData = await activeRoute.fetchInitialData(initialFetchReq); routeData = await activeRoute.fetchInitialData(initialFetchReq);

View file

@ -69,7 +69,7 @@ const signals = {
const exit_signal = 128; // Fatal error signal code on Linux systems const exit_signal = 128; // Fatal error signal code on Linux systems
const exit_timeout = 8000; // Because Docker SIGTERMs after 10 secs const exit_timeout = 8000; // Because Docker SIGTERMs after 10 secs
const shutdown = (signal, value) => { function shutdown(signal: string, value: number) {
// TODO: Should set a flag here for the listener to reject any further // TODO: Should set a flag here for the listener to reject any further
// incoming connections with a HTTP 503 error while shutting down. // incoming connections with a HTTP 503 error while shutting down.
// Otherwise the connection count may not reach zero before timeout. // Otherwise the connection count may not reach zero before timeout.
@ -83,7 +83,7 @@ const shutdown = (signal, value) => {
); );
process.exit(exit_signal + value); process.exit(exit_signal + value);
}, exit_timeout); }, exit_timeout);
}; }
for (const [signal, value] of Object.entries(signals)) { for (const [signal, value] of Object.entries(signals)) {
process.on(signal, () => { process.on(signal, () => {

View file

@ -1,6 +1,6 @@
import * as crypto from "crypto"; import * as crypto from "crypto";
import type { NextFunction, Request, Response } from "express"; import type { NextFunction, Request, Response } from "express";
import { hasJwtCookie } from "./utils/has-jwt-cookie"; import { getJwtCookie } from "./utils/has-jwt-cookie";
export function setDefaultCsp({ export function setDefaultCsp({
res, res,
@ -52,7 +52,7 @@ export function setCacheControl(
// Static content gets cached publicly for a day // Static content gets cached publicly for a day
caching = "public, max-age=86400"; caching = "public, max-age=86400";
} else { } else {
if (hasJwtCookie(req)) { if (getJwtCookie(req.headers)) {
caching = "private"; caching = "private";
} else { } else {
caching = "public, max-age=60"; caching = "public, max-age=60";

View file

@ -1,9 +1,9 @@
import * as cookie from "cookie"; import * as cookie from "cookie";
import type { Request } from "express";
import { authCookieName } from "../../shared/config"; import { authCookieName } from "../../shared/config";
import { IncomingHttpHeaders } from "http";
export function hasJwtCookie(req: Request): boolean { export function getJwtCookie(headers: IncomingHttpHeaders): string | undefined {
return Boolean( return headers.cookie
cookie.parse(req.headers.cookie ?? "")[authCookieName]?.length, ? cookie.parse(headers.cookie)[authCookieName] // This can actually be undefined
); : undefined;
} }

View file

@ -1,4 +1,5 @@
import { IncomingHttpHeaders } from "http"; import { IncomingHttpHeaders } from "http";
import { getJwtCookie } from "./has-jwt-cookie";
export function setForwardedHeaders(headers: IncomingHttpHeaders): { export function setForwardedHeaders(headers: IncomingHttpHeaders): {
[key: string]: string; [key: string]: string;
@ -21,5 +22,11 @@ export function setForwardedHeaders(headers: IncomingHttpHeaders): {
out["x-forwarded-for"] = forwardedFor as string; out["x-forwarded-for"] = forwardedFor as string;
} }
const auth = getJwtCookie(headers);
if (auth) {
out["Authorization"] = `Bearer ${auth}`;
}
return out; return out;
} }

View file

@ -11,6 +11,7 @@ import { Component, linkEvent } from "inferno";
import { import {
CommunityResponse, CommunityResponse,
GetSiteResponse, GetSiteResponse,
LemmyHttp,
ListCommunities, ListCommunities,
ListCommunitiesResponse, ListCommunitiesResponse,
ListingType, ListingType,
@ -23,6 +24,7 @@ import {
HttpService, HttpService,
LOADING_REQUEST, LOADING_REQUEST,
RequestState, RequestState,
wrapClient,
} from "../../services/HttpService"; } from "../../services/HttpService";
import { HtmlTags } from "../common/html-tags"; import { HtmlTags } from "../common/html-tags";
import { Spinner } from "../common/icon"; import { Spinner } from "../common/icon";
@ -33,6 +35,7 @@ import { CommunityLink } from "./community-link";
import { communityLimit } from "../../config"; import { communityLimit } from "../../config";
import { SubscribeButton } from "../common/subscribe-button"; import { SubscribeButton } from "../common/subscribe-button";
import { getHttpBaseInternal } from "../../utils/env";
type CommunitiesData = RouteDataResponse<{ type CommunitiesData = RouteDataResponse<{
listCommunitiesResponse: ListCommunitiesResponse; listCommunitiesResponse: ListCommunitiesResponse;
@ -306,11 +309,14 @@ export class Communities extends Component<any, CommunitiesState> {
} }
static async fetchInitialData({ static async fetchInitialData({
headers,
query: { listingType, sort, page }, query: { listingType, sort, page },
client,
}: InitialFetchRequest< }: InitialFetchRequest<
QueryParams<CommunitiesProps> QueryParams<CommunitiesProps>
>): Promise<CommunitiesData> { >): Promise<CommunitiesData> {
const client = wrapClient(
new LemmyHttp(getHttpBaseInternal(), { headers }),
);
const listCommunitiesForm: ListCommunities = { const listCommunitiesForm: ListCommunities = {
type_: getListingTypeFromQuery(listingType), type_: getListingTypeFromQuery(listingType),
sort: getSortTypeFromQuery(sort), sort: getSortTypeFromQuery(sort),

View file

@ -54,6 +54,7 @@ import {
GetPosts, GetPosts,
GetPostsResponse, GetPostsResponse,
GetSiteResponse, GetSiteResponse,
LemmyHttp,
LockPost, LockPost,
MarkCommentReplyAsRead, MarkCommentReplyAsRead,
MarkPersonMentionAsRead, MarkPersonMentionAsRead,
@ -84,6 +85,7 @@ import {
HttpService, HttpService,
LOADING_REQUEST, LOADING_REQUEST,
RequestState, RequestState,
wrapClient,
} from "../../services/HttpService"; } from "../../services/HttpService";
import { setupTippy } from "../../tippy"; import { setupTippy } from "../../tippy";
import { toast } from "../../toast"; import { toast } from "../../toast";
@ -98,6 +100,7 @@ import { SiteSidebar } from "../home/site-sidebar";
import { PostListings } from "../post/post-listings"; import { PostListings } from "../post/post-listings";
import { CommunityLink } from "./community-link"; import { CommunityLink } from "./community-link";
import { PaginatorCursor } from "../common/paginator-cursor"; import { PaginatorCursor } from "../common/paginator-cursor";
import { getHttpBaseInternal } from "../../utils/env";
type CommunityData = RouteDataResponse<{ type CommunityData = RouteDataResponse<{
communityRes: GetCommunityResponse; communityRes: GetCommunityResponse;
@ -230,12 +233,15 @@ export class Community extends Component<
} }
static async fetchInitialData({ static async fetchInitialData({
client, headers,
path, path,
query: { dataType: urlDataType, pageCursor, sort: urlSort }, query: { dataType: urlDataType, pageCursor, sort: urlSort },
}: InitialFetchRequest<QueryParams<CommunityProps>>): Promise< }: InitialFetchRequest<QueryParams<CommunityProps>>): Promise<
Promise<CommunityData> Promise<CommunityData>
> { > {
const client = wrapClient(
new LemmyHttp(getHttpBaseInternal(), { headers }),
);
const pathSplit = path.split("/"); const pathSplit = path.split("/");
const communityName = pathSplit[2]; const communityName = pathSplit[2];

View file

@ -11,6 +11,7 @@ import {
EditSite, EditSite,
GetFederatedInstancesResponse, GetFederatedInstancesResponse,
GetSiteResponse, GetSiteResponse,
LemmyHttp,
PersonView, PersonView,
} from "lemmy-js-client"; } from "lemmy-js-client";
import { InitialFetchRequest } from "../../interfaces"; import { InitialFetchRequest } from "../../interfaces";
@ -21,6 +22,7 @@ import {
HttpService, HttpService,
LOADING_REQUEST, LOADING_REQUEST,
RequestState, RequestState,
wrapClient,
} from "../../services/HttpService"; } from "../../services/HttpService";
import { toast } from "../../toast"; import { toast } from "../../toast";
import { HtmlTags } from "../common/html-tags"; import { HtmlTags } from "../common/html-tags";
@ -31,6 +33,7 @@ import { EmojiForm } from "./emojis-form";
import RateLimitForm from "./rate-limit-form"; import RateLimitForm from "./rate-limit-form";
import { SiteForm } from "./site-form"; import { SiteForm } from "./site-form";
import { TaglineForm } from "./tagline-form"; import { TaglineForm } from "./tagline-form";
import { getHttpBaseInternal } from "../../utils/env";
type AdminSettingsData = RouteDataResponse<{ type AdminSettingsData = RouteDataResponse<{
bannedRes: BannedPersonsResponse; bannedRes: BannedPersonsResponse;
@ -85,8 +88,11 @@ export class AdminSettings extends Component<any, AdminSettingsState> {
} }
static async fetchInitialData({ static async fetchInitialData({
client, headers,
}: InitialFetchRequest): Promise<AdminSettingsData> { }: InitialFetchRequest): Promise<AdminSettingsData> {
const client = wrapClient(
new LemmyHttp(getHttpBaseInternal(), { headers }),
);
return { return {
bannedRes: await client.getBannedPersons(), bannedRes: await client.getBannedPersons(),
instancesRes: await client.getFederatedInstances(), instancesRes: await client.getFederatedInstances(),

View file

@ -52,6 +52,7 @@ import {
GetPosts, GetPosts,
GetPostsResponse, GetPostsResponse,
GetSiteResponse, GetSiteResponse,
LemmyHttp,
ListCommunities, ListCommunities,
ListCommunitiesResponse, ListCommunitiesResponse,
ListingType, ListingType,
@ -84,6 +85,7 @@ import {
HttpService, HttpService,
LOADING_REQUEST, LOADING_REQUEST,
RequestState, RequestState,
wrapClient,
} from "../../services/HttpService"; } from "../../services/HttpService";
import { setupTippy } from "../../tippy"; import { setupTippy } from "../../tippy";
import { toast } from "../../toast"; import { toast } from "../../toast";
@ -97,6 +99,7 @@ import { CommunityLink } from "../community/community-link";
import { PostListings } from "../post/post-listings"; import { PostListings } from "../post/post-listings";
import { SiteSidebar } from "./site-sidebar"; import { SiteSidebar } from "./site-sidebar";
import { PaginatorCursor } from "../common/paginator-cursor"; import { PaginatorCursor } from "../common/paginator-cursor";
import { getHttpBaseInternal } from "../../utils/env";
interface HomeState { interface HomeState {
postsRes: RequestState<GetPostsResponse>; postsRes: RequestState<GetPostsResponse>;
@ -163,18 +166,21 @@ function getDataTypeFromQuery(type?: string): DataType {
return type ? DataType[type] : DataType.Post; return type ? DataType[type] : DataType.Post;
} }
function getListingTypeFromQuery(type?: string): ListingType | undefined { function getListingTypeFromQuery(
type?: string,
myUserInfo = UserService.Instance.myUserInfo,
): ListingType | undefined {
const myListingType = const myListingType =
UserService.Instance.myUserInfo?.local_user_view?.local_user myUserInfo?.local_user_view?.local_user?.default_listing_type;
?.default_listing_type;
return type ? (type as ListingType) : myListingType; return type ? (type as ListingType) : myListingType;
} }
function getSortTypeFromQuery(type?: string): SortType { function getSortTypeFromQuery(
const mySortType = type?: string,
UserService.Instance.myUserInfo?.local_user_view?.local_user myUserInfo = UserService.Instance.myUserInfo,
?.default_sort_type; ): SortType {
const mySortType = myUserInfo?.local_user_view?.local_user?.default_sort_type;
return (type ? (type as SortType) : mySortType) ?? "Active"; return (type ? (type as SortType) : mySortType) ?? "Active";
} }
@ -303,15 +309,19 @@ export class Home extends Component<any, HomeState> {
} }
static async fetchInitialData({ static async fetchInitialData({
client,
query: { dataType: urlDataType, listingType, pageCursor, sort: urlSort }, query: { dataType: urlDataType, listingType, pageCursor, sort: urlSort },
site, site,
headers,
}: InitialFetchRequest<QueryParams<HomeProps>>): Promise<HomeData> { }: InitialFetchRequest<QueryParams<HomeProps>>): Promise<HomeData> {
const client = wrapClient(
new LemmyHttp(getHttpBaseInternal(), { headers }),
);
const dataType = getDataTypeFromQuery(urlDataType); const dataType = getDataTypeFromQuery(urlDataType);
const type_ = const type_ =
getListingTypeFromQuery(listingType) ?? getListingTypeFromQuery(listingType, site.my_user) ??
site.site_view.local_site.default_post_listing_type; site.site_view.local_site.default_post_listing_type;
const sort = getSortTypeFromQuery(urlSort); const sort = getSortTypeFromQuery(urlSort, site.my_user);
let postsRes: RequestState<GetPostsResponse> = EMPTY_REQUEST; let postsRes: RequestState<GetPostsResponse> = EMPTY_REQUEST;
let commentsRes: RequestState<GetCommentsResponse> = EMPTY_REQUEST; let commentsRes: RequestState<GetCommentsResponse> = EMPTY_REQUEST;

View file

@ -5,6 +5,7 @@ import {
GetFederatedInstancesResponse, GetFederatedInstancesResponse,
GetSiteResponse, GetSiteResponse,
Instance, Instance,
LemmyHttp,
} from "lemmy-js-client"; } from "lemmy-js-client";
import classNames from "classnames"; import classNames from "classnames";
import { relTags } from "../../config"; import { relTags } from "../../config";
@ -15,10 +16,12 @@ import {
HttpService, HttpService,
LOADING_REQUEST, LOADING_REQUEST,
RequestState, RequestState,
wrapClient,
} from "../../services/HttpService"; } from "../../services/HttpService";
import { HtmlTags } from "../common/html-tags"; import { HtmlTags } from "../common/html-tags";
import { Spinner } from "../common/icon"; import { Spinner } from "../common/icon";
import Tabs from "../common/tabs"; import Tabs from "../common/tabs";
import { getHttpBaseInternal } from "../../utils/env";
type InstancesData = RouteDataResponse<{ type InstancesData = RouteDataResponse<{
federatedInstancesResponse: GetFederatedInstancesResponse; federatedInstancesResponse: GetFederatedInstancesResponse;
@ -68,8 +71,11 @@ export class Instances extends Component<any, InstancesState> {
} }
static async fetchInitialData({ static async fetchInitialData({
client, headers,
}: InitialFetchRequest): Promise<InstancesData> { }: InitialFetchRequest): Promise<InstancesData> {
const client = wrapClient(
new LemmyHttp(getHttpBaseInternal(), { headers }),
);
return { return {
federatedInstancesResponse: await client.getFederatedInstances(), federatedInstancesResponse: await client.getFederatedInstances(),
}; };

View file

@ -31,6 +31,7 @@ import {
GetModlogResponse, GetModlogResponse,
GetPersonDetails, GetPersonDetails,
GetPersonDetailsResponse, GetPersonDetailsResponse,
LemmyHttp,
ModAddCommunityView, ModAddCommunityView,
ModAddView, ModAddView,
ModBanFromCommunityView, ModBanFromCommunityView,
@ -52,6 +53,7 @@ import {
HttpService, HttpService,
LOADING_REQUEST, LOADING_REQUEST,
RequestState, RequestState,
wrapClient,
} from "../services/HttpService"; } from "../services/HttpService";
import { HtmlTags } from "./common/html-tags"; import { HtmlTags } from "./common/html-tags";
import { Icon, Spinner } from "./common/icon"; import { Icon, Spinner } from "./common/icon";
@ -60,6 +62,7 @@ import { Paginator } from "./common/paginator";
import { SearchableSelect } from "./common/searchable-select"; import { SearchableSelect } from "./common/searchable-select";
import { CommunityLink } from "./community/community-link"; import { CommunityLink } from "./community/community-link";
import { PersonListing } from "./person/person-listing"; import { PersonListing } from "./person/person-listing";
import { getHttpBaseInternal } from "../utils/env";
type FilterType = "mod" | "user"; type FilterType = "mod" | "user";
@ -1004,11 +1007,14 @@ export class Modlog extends Component<
} }
static async fetchInitialData({ static async fetchInitialData({
client, headers,
path, path,
query: { modId: urlModId, page, userId: urlUserId, actionType }, query: { modId: urlModId, page, userId: urlUserId, actionType },
site, site,
}: InitialFetchRequest<QueryParams<ModlogProps>>): Promise<ModlogData> { }: InitialFetchRequest<QueryParams<ModlogProps>>): Promise<ModlogData> {
const client = wrapClient(
new LemmyHttp(getHttpBaseInternal(), { headers }),
);
const pathSplit = path.split("/"); const pathSplit = path.split("/");
const communityId = getIdFromString(pathSplit[2]); const communityId = getIdFromString(pathSplit[2]);
const modId = !site.site_view.local_site.hide_modlog_mod_names const modId = !site.site_view.local_site.hide_modlog_mod_names

View file

@ -42,6 +42,7 @@ import {
GetPersonMentionsResponse, GetPersonMentionsResponse,
GetRepliesResponse, GetRepliesResponse,
GetSiteResponse, GetSiteResponse,
LemmyHttp,
MarkCommentReplyAsRead, MarkCommentReplyAsRead,
MarkPersonMentionAsRead, MarkPersonMentionAsRead,
MarkPrivateMessageAsRead, MarkPrivateMessageAsRead,
@ -69,6 +70,7 @@ import {
HttpService, HttpService,
LOADING_REQUEST, LOADING_REQUEST,
RequestState, RequestState,
wrapClient,
} from "../../services/HttpService"; } from "../../services/HttpService";
import { toast } from "../../toast"; import { toast } from "../../toast";
import { CommentNodes } from "../comment/comment-nodes"; import { CommentNodes } from "../comment/comment-nodes";
@ -77,6 +79,7 @@ import { HtmlTags } from "../common/html-tags";
import { Icon, Spinner } from "../common/icon"; import { Icon, Spinner } from "../common/icon";
import { Paginator } from "../common/paginator"; import { Paginator } from "../common/paginator";
import { PrivateMessage } from "../private_message/private-message"; import { PrivateMessage } from "../private_message/private-message";
import { getHttpBaseInternal } from "../../utils/env";
enum UnreadOrAll { enum UnreadOrAll {
Unread, Unread,
@ -724,8 +727,11 @@ export class Inbox extends Component<any, InboxState> {
} }
static async fetchInitialData({ static async fetchInitialData({
client, headers,
}: InitialFetchRequest): Promise<InboxData> { }: InitialFetchRequest): Promise<InboxData> {
const client = wrapClient(
new LemmyHttp(getHttpBaseInternal(), { headers }),
);
const sort: CommentSortType = "New"; const sort: CommentSortType = "New";
const empty: EmptyRequestState = EMPTY_REQUEST; const empty: EmptyRequestState = EMPTY_REQUEST;
let inboxData: InboxData = { let inboxData: InboxData = {
@ -734,7 +740,7 @@ export class Inbox extends Component<any, InboxState> {
repliesRes: empty, repliesRes: empty,
}; };
if (myAuth()) { if (headers["Authorization"]) {
const [mentionsRes, messagesRes, repliesRes] = await Promise.all([ const [mentionsRes, messagesRes, repliesRes] = await Promise.all([
client.getPersonMentions({ client.getPersonMentions({
sort, sort,

View file

@ -55,6 +55,7 @@ import {
GetPersonDetails, GetPersonDetails,
GetPersonDetailsResponse, GetPersonDetailsResponse,
GetSiteResponse, GetSiteResponse,
LemmyHttp,
LockPost, LockPost,
MarkCommentReplyAsRead, MarkCommentReplyAsRead,
MarkPersonMentionAsRead, MarkPersonMentionAsRead,
@ -80,6 +81,7 @@ import {
HttpService, HttpService,
LOADING_REQUEST, LOADING_REQUEST,
RequestState, RequestState,
wrapClient,
} from "../../services/HttpService"; } from "../../services/HttpService";
import { setupTippy } from "../../tippy"; import { setupTippy } from "../../tippy";
import { toast } from "../../toast"; import { toast } from "../../toast";
@ -92,6 +94,7 @@ import { UserBadges } from "../common/user-badges";
import { CommunityLink } from "../community/community-link"; import { CommunityLink } from "../community/community-link";
import { PersonDetails } from "./person-details"; import { PersonDetails } from "./person-details";
import { PersonListing } from "./person-listing"; import { PersonListing } from "./person-listing";
import { getHttpBaseInternal } from "../../utils/env";
type ProfileData = RouteDataResponse<{ type ProfileData = RouteDataResponse<{
personResponse: GetPersonDetailsResponse; personResponse: GetPersonDetailsResponse;
@ -275,10 +278,13 @@ export class Profile extends Component<
} }
static async fetchInitialData({ static async fetchInitialData({
client, headers,
path, path,
query: { page, sort, view: urlView }, query: { page, sort, view: urlView },
}: InitialFetchRequest<QueryParams<ProfileProps>>): Promise<ProfileData> { }: InitialFetchRequest<QueryParams<ProfileProps>>): Promise<ProfileData> {
const client = wrapClient(
new LemmyHttp(getHttpBaseInternal(), { headers }),
);
const pathSplit = path.split("/"); const pathSplit = path.split("/");
const username = pathSplit[2]; const username = pathSplit[2];

View file

@ -1,4 +1,4 @@
import { editRegistrationApplication, myAuth, setIsoData } from "@utils/app"; import { editRegistrationApplication, setIsoData } from "@utils/app";
import { randomStr } from "@utils/helpers"; import { randomStr } from "@utils/helpers";
import { RouteDataResponse } from "@utils/types"; import { RouteDataResponse } from "@utils/types";
import classNames from "classnames"; import classNames from "classnames";
@ -6,6 +6,7 @@ import { Component, linkEvent } from "inferno";
import { import {
ApproveRegistrationApplication, ApproveRegistrationApplication,
GetSiteResponse, GetSiteResponse,
LemmyHttp,
ListRegistrationApplicationsResponse, ListRegistrationApplicationsResponse,
RegistrationApplicationView, RegistrationApplicationView,
} from "lemmy-js-client"; } from "lemmy-js-client";
@ -17,6 +18,7 @@ import {
HttpService, HttpService,
LOADING_REQUEST, LOADING_REQUEST,
RequestState, RequestState,
wrapClient,
} from "../../services/HttpService"; } from "../../services/HttpService";
import { setupTippy } from "../../tippy"; import { setupTippy } from "../../tippy";
import { HtmlTags } from "../common/html-tags"; import { HtmlTags } from "../common/html-tags";
@ -24,6 +26,7 @@ import { Spinner } from "../common/icon";
import { Paginator } from "../common/paginator"; import { Paginator } from "../common/paginator";
import { RegistrationApplication } from "../common/registration-application"; import { RegistrationApplication } from "../common/registration-application";
import { UnreadCounterService } from "../../services"; import { UnreadCounterService } from "../../services";
import { getHttpBaseInternal } from "../../utils/env";
enum UnreadOrAll { enum UnreadOrAll {
Unread, Unread,
@ -207,10 +210,13 @@ export class RegistrationApplications extends Component<
} }
static async fetchInitialData({ static async fetchInitialData({
client, headers,
}: InitialFetchRequest): Promise<RegistrationApplicationsData> { }: InitialFetchRequest): Promise<RegistrationApplicationsData> {
const client = wrapClient(
new LemmyHttp(getHttpBaseInternal(), { headers }),
);
return { return {
listRegistrationApplicationsResponse: myAuth() listRegistrationApplicationsResponse: headers["Authorization"]
? await client.listRegistrationApplications({ ? await client.listRegistrationApplications({
unread_only: true, unread_only: true,
page: 1, page: 1,

View file

@ -13,6 +13,7 @@ import {
CommentReportResponse, CommentReportResponse,
CommentReportView, CommentReportView,
GetSiteResponse, GetSiteResponse,
LemmyHttp,
ListCommentReports, ListCommentReports,
ListCommentReportsResponse, ListCommentReportsResponse,
ListPostReports, ListPostReports,
@ -39,6 +40,7 @@ import {
EMPTY_REQUEST, EMPTY_REQUEST,
LOADING_REQUEST, LOADING_REQUEST,
RequestState, RequestState,
wrapClient,
} from "../../services/HttpService"; } from "../../services/HttpService";
import { CommentReport } from "../comment/comment-report"; import { CommentReport } from "../comment/comment-report";
import { HtmlTags } from "../common/html-tags"; import { HtmlTags } from "../common/html-tags";
@ -47,6 +49,7 @@ import { Paginator } from "../common/paginator";
import { PostReport } from "../post/post-report"; import { PostReport } from "../post/post-report";
import { PrivateMessageReport } from "../private_message/private-message-report"; import { PrivateMessageReport } from "../private_message/private-message-report";
import { UnreadCounterService } from "../../services"; import { UnreadCounterService } from "../../services";
import { getHttpBaseInternal } from "../../utils/env";
enum UnreadOrAll { enum UnreadOrAll {
Unread, Unread,
@ -535,8 +538,11 @@ export class Reports extends Component<any, ReportsState> {
} }
static async fetchInitialData({ static async fetchInitialData({
client, headers,
}: InitialFetchRequest): Promise<ReportsData> { }: InitialFetchRequest): Promise<ReportsData> {
const client = wrapClient(
new LemmyHttp(getHttpBaseInternal(), { headers }),
);
const unresolved_only = true; const unresolved_only = true;
const page = 1; const page = 1;
const limit = fetchLimit; const limit = fetchLimit;

View file

@ -28,6 +28,7 @@ import {
GetSiteResponse, GetSiteResponse,
Instance, Instance,
InstanceBlockView, InstanceBlockView,
LemmyHttp,
ListingType, ListingType,
LoginResponse, LoginResponse,
PersonBlockView, PersonBlockView,
@ -42,6 +43,7 @@ import {
HttpService, HttpService,
LOADING_REQUEST, LOADING_REQUEST,
RequestState, RequestState,
wrapClient,
} from "../../services/HttpService"; } from "../../services/HttpService";
import { I18NextService, languages } from "../../services/I18NextService"; import { I18NextService, languages } from "../../services/I18NextService";
import { setupTippy } from "../../tippy"; import { setupTippy } from "../../tippy";
@ -61,7 +63,8 @@ import { PersonListing } from "./person-listing";
import { InitialFetchRequest } from "../../interfaces"; import { InitialFetchRequest } from "../../interfaces";
import TotpModal from "../common/totp-modal"; import TotpModal from "../common/totp-modal";
import { LoadingEllipses } from "../common/loading-ellipses"; import { LoadingEllipses } from "../common/loading-ellipses";
import { updateDataBsTheme } from "@utils/browser"; import { updateDataBsTheme } from "../../utils/browser";
import { getHttpBaseInternal } from "../../utils/env";
type SettingsData = RouteDataResponse<{ type SettingsData = RouteDataResponse<{
instancesRes: GetFederatedInstancesResponse; instancesRes: GetFederatedInstancesResponse;
@ -332,8 +335,11 @@ export class Settings extends Component<any, SettingsState> {
} }
static async fetchInitialData({ static async fetchInitialData({
client, headers,
}: InitialFetchRequest): Promise<SettingsData> { }: InitialFetchRequest): Promise<SettingsData> {
const client = wrapClient(
new LemmyHttp(getHttpBaseInternal(), { headers }),
);
return { return {
instancesRes: await client.getFederatedInstances(), instancesRes: await client.getFederatedInstances(),
}; };

View file

@ -9,6 +9,7 @@ import {
GetCommunity, GetCommunity,
GetCommunityResponse, GetCommunityResponse,
GetSiteResponse, GetSiteResponse,
LemmyHttp,
ListCommunitiesResponse, ListCommunitiesResponse,
} from "lemmy-js-client"; } from "lemmy-js-client";
import { InitialFetchRequest, PostFormParams } from "../../interfaces"; import { InitialFetchRequest, PostFormParams } from "../../interfaces";
@ -18,10 +19,12 @@ import {
HttpService, HttpService,
RequestState, RequestState,
WrappedLemmyHttp, WrappedLemmyHttp,
wrapClient,
} from "../../services/HttpService"; } from "../../services/HttpService";
import { HtmlTags } from "../common/html-tags"; import { HtmlTags } from "../common/html-tags";
import { Spinner } from "../common/icon"; import { Spinner } from "../common/icon";
import { PostForm } from "./post-form"; import { PostForm } from "./post-form";
import { getHttpBaseInternal } from "../../utils/env";
export interface CreatePostProps { export interface CreatePostProps {
communityId?: number; communityId?: number;
@ -236,11 +239,14 @@ export class CreatePost extends Component<
} }
static async fetchInitialData({ static async fetchInitialData({
client, headers,
query: { communityId }, query: { communityId },
}: InitialFetchRequest< }: InitialFetchRequest<
QueryParams<CreatePostProps> QueryParams<CreatePostProps>
>): Promise<CreatePostData> { >): Promise<CreatePostData> {
const client = wrapClient(
new LemmyHttp(getHttpBaseInternal(), { headers }),
);
const data: CreatePostData = { const data: CreatePostData = {
initialCommunitiesRes: await fetchCommunitiesForOptions(client), initialCommunitiesRes: await fetchCommunitiesForOptions(client),
communityResponse: EMPTY_REQUEST, communityResponse: EMPTY_REQUEST,

View file

@ -59,6 +59,7 @@ import {
GetPost, GetPost,
GetPostResponse, GetPostResponse,
GetSiteResponse, GetSiteResponse,
LemmyHttp,
LockPost, LockPost,
MarkCommentReplyAsRead, MarkCommentReplyAsRead,
PostResponse, PostResponse,
@ -86,6 +87,7 @@ import {
HttpService, HttpService,
LOADING_REQUEST, LOADING_REQUEST,
RequestState, RequestState,
wrapClient,
} from "../../services/HttpService"; } from "../../services/HttpService";
import { setupTippy } from "../../tippy"; import { setupTippy } from "../../tippy";
import { toast } from "../../toast"; import { toast } from "../../toast";
@ -95,6 +97,7 @@ import { HtmlTags } from "../common/html-tags";
import { Icon, Spinner } from "../common/icon"; import { Icon, Spinner } from "../common/icon";
import { Sidebar } from "../community/sidebar"; import { Sidebar } from "../community/sidebar";
import { PostListing } from "./post-listing"; import { PostListing } from "./post-listing";
import { getHttpBaseInternal } from "../../utils/env";
const commentsShownInterval = 15; const commentsShownInterval = 15;
@ -231,9 +234,12 @@ export class Post extends Component<any, PostState> {
} }
static async fetchInitialData({ static async fetchInitialData({
client, headers,
path, path,
}: InitialFetchRequest): Promise<PostData> { }: InitialFetchRequest): Promise<PostData> {
const client = wrapClient(
new LemmyHttp(getHttpBaseInternal(), { headers }),
);
const pathSplit = path.split("/"); const pathSplit = path.split("/");
const pathType = pathSplit.at(1); const pathType = pathSplit.at(1);

View file

@ -6,6 +6,7 @@ import {
GetPersonDetails, GetPersonDetails,
GetPersonDetailsResponse, GetPersonDetailsResponse,
GetSiteResponse, GetSiteResponse,
LemmyHttp,
} from "lemmy-js-client"; } from "lemmy-js-client";
import { InitialFetchRequest } from "../../interfaces"; import { InitialFetchRequest } from "../../interfaces";
import { FirstLoadService, I18NextService } from "../../services"; import { FirstLoadService, I18NextService } from "../../services";
@ -14,11 +15,13 @@ import {
HttpService, HttpService,
LOADING_REQUEST, LOADING_REQUEST,
RequestState, RequestState,
wrapClient,
} from "../../services/HttpService"; } from "../../services/HttpService";
import { toast } from "../../toast"; import { toast } from "../../toast";
import { HtmlTags } from "../common/html-tags"; import { HtmlTags } from "../common/html-tags";
import { Spinner } from "../common/icon"; import { Spinner } from "../common/icon";
import { PrivateMessageForm } from "./private-message-form"; import { PrivateMessageForm } from "./private-message-form";
import { getHttpBaseInternal } from "../../utils/env";
type CreatePrivateMessageData = RouteDataResponse<{ type CreatePrivateMessageData = RouteDataResponse<{
recipientDetailsResponse: GetPersonDetailsResponse; recipientDetailsResponse: GetPersonDetailsResponse;
@ -65,9 +68,12 @@ export class CreatePrivateMessage extends Component<
} }
static async fetchInitialData({ static async fetchInitialData({
client, headers,
path, path,
}: InitialFetchRequest): Promise<CreatePrivateMessageData> { }: InitialFetchRequest): Promise<CreatePrivateMessageData> {
const client = wrapClient(
new LemmyHttp(getHttpBaseInternal(), { headers }),
);
const person_id = Number(path.split("/").pop()); const person_id = Number(path.split("/").pop());
const form: GetPersonDetails = { const form: GetPersonDetails = {

View file

@ -2,13 +2,18 @@ import { setIsoData } from "@utils/app";
import { getQueryParams } from "@utils/helpers"; import { getQueryParams } from "@utils/helpers";
import { QueryParams, RouteDataResponse } from "@utils/types"; import { QueryParams, RouteDataResponse } from "@utils/types";
import { Component, linkEvent } from "inferno"; import { Component, linkEvent } from "inferno";
import { CommunityView, ResolveObjectResponse } from "lemmy-js-client"; import {
CommunityView,
LemmyHttp,
ResolveObjectResponse,
} from "lemmy-js-client";
import { InitialFetchRequest } from "../interfaces"; import { InitialFetchRequest } from "../interfaces";
import { FirstLoadService, HttpService, I18NextService } from "../services"; import { FirstLoadService, HttpService, I18NextService } from "../services";
import { import {
EMPTY_REQUEST, EMPTY_REQUEST,
LOADING_REQUEST, LOADING_REQUEST,
RequestState, RequestState,
wrapClient,
} from "../services/HttpService"; } from "../services/HttpService";
import { HtmlTags } from "./common/html-tags"; import { HtmlTags } from "./common/html-tags";
import { Spinner } from "./common/icon"; import { Spinner } from "./common/icon";
@ -16,6 +21,7 @@ import { LoadingEllipses } from "./common/loading-ellipses";
import { PictrsImage } from "./common/pictrs-image"; import { PictrsImage } from "./common/pictrs-image";
import { SubscribeButton } from "./common/subscribe-button"; import { SubscribeButton } from "./common/subscribe-button";
import { CommunityLink } from "./community/community-link"; import { CommunityLink } from "./community/community-link";
import { getHttpBaseInternal } from "../utils/env";
interface RemoteFetchProps { interface RemoteFetchProps {
uri?: string; uri?: string;
@ -206,15 +212,17 @@ export class RemoteFetch extends Component<any, RemoteFetchState> {
} }
static async fetchInitialData({ static async fetchInitialData({
auth, headers,
client,
query: { uri }, query: { uri },
}: InitialFetchRequest< }: InitialFetchRequest<
QueryParams<RemoteFetchProps> QueryParams<RemoteFetchProps>
>): Promise<RemoteFetchData> { >): Promise<RemoteFetchData> {
const client = wrapClient(
new LemmyHttp(getHttpBaseInternal(), { headers }),
);
const data: RemoteFetchData = { resolveObjectRes: EMPTY_REQUEST }; const data: RemoteFetchData = { resolveObjectRes: EMPTY_REQUEST };
if (uri && auth) { if (uri && headers["Authorization"]) {
data.resolveObjectRes = await client.resolveObject({ data.resolveObjectRes = await client.resolveObject({
q: uriToQuery(uri), q: uriToQuery(uri),
}); });

View file

@ -34,6 +34,7 @@ import {
GetPersonDetails, GetPersonDetails,
GetPersonDetailsResponse, GetPersonDetailsResponse,
GetSiteResponse, GetSiteResponse,
LemmyHttp,
ListCommunitiesResponse, ListCommunitiesResponse,
ListingType, ListingType,
PersonView, PersonView,
@ -53,6 +54,7 @@ import {
HttpService, HttpService,
LOADING_REQUEST, LOADING_REQUEST,
RequestState, RequestState,
wrapClient,
} from "../services/HttpService"; } from "../services/HttpService";
import { CommentNodes } from "./comment/comment-nodes"; import { CommentNodes } from "./comment/comment-nodes";
import { HtmlTags } from "./common/html-tags"; import { HtmlTags } from "./common/html-tags";
@ -64,6 +66,7 @@ import { SortSelect } from "./common/sort-select";
import { CommunityLink } from "./community/community-link"; import { CommunityLink } from "./community/community-link";
import { PersonListing } from "./person/person-listing"; import { PersonListing } from "./person/person-listing";
import { PostListing } from "./post/post-listing"; import { PostListing } from "./post/post-listing";
import { getHttpBaseInternal } from "../utils/env";
interface SearchProps { interface SearchProps {
q?: string; q?: string;
@ -386,9 +389,12 @@ export class Search extends Component<any, SearchState> {
} }
static async fetchInitialData({ static async fetchInitialData({
client, headers,
query: { communityId, creatorId, q, type, sort, listingType, page }, query: { communityId, creatorId, q, type, sort, listingType, page },
}: InitialFetchRequest<QueryParams<SearchProps>>): Promise<SearchData> { }: InitialFetchRequest<QueryParams<SearchProps>>): Promise<SearchData> {
const client = wrapClient(
new LemmyHttp(getHttpBaseInternal(), { headers }),
);
const community_id = getIdFromString(communityId); const community_id = getIdFromString(communityId);
let communityResponse: RequestState<GetCommunityResponse> = EMPTY_REQUEST; let communityResponse: RequestState<GetCommunityResponse> = EMPTY_REQUEST;
if (community_id) { if (community_id) {
@ -435,7 +441,7 @@ export class Search extends Component<any, SearchState> {
}; };
searchResponse = await client.search(form); searchResponse = await client.search(form);
if (myAuth()) { if (headers["Authorization"]) {
const resolveObjectForm: ResolveObject = { const resolveObjectForm: ResolveObject = {
q: query, q: query,
}; };

View file

@ -1,7 +1,7 @@
import { ErrorPageData } from "@utils/types"; import { ErrorPageData } from "@utils/types";
import { CommentView, GetSiteResponse } from "lemmy-js-client"; import { CommentView, GetSiteResponse } from "lemmy-js-client";
import type { ParsedQs } from "qs"; import type { ParsedQs } from "qs";
import { RequestState, WrappedLemmyHttp } from "./services/HttpService"; import { RequestState } from "./services/HttpService";
/** /**
* This contains serialized data, it needs to be deserialized before use. * This contains serialized data, it needs to be deserialized before use.
@ -25,11 +25,10 @@ declare global {
} }
export interface InitialFetchRequest<T extends ParsedQs = ParsedQs> { export interface InitialFetchRequest<T extends ParsedQs = ParsedQs> {
client: WrappedLemmyHttp;
path: string; path: string;
query: T; query: T;
site: GetSiteResponse; site: GetSiteResponse;
auth?: string; headers: { [key: string]: string };
} }
export interface PostFormParams { export interface PostFormParams {

View file

@ -1,5 +1,6 @@
import { UserService } from "../../services"; import { UserService } from "../../services";
// Warning, do not use this in fetchInitialData
export default function myAuth(): string | undefined { export default function myAuth(): string | undefined {
return UserService.Instance.auth(); return UserService.Instance.auth();
} }

View file

@ -1,16 +1,5 @@
import { Person } from "lemmy-js-client"; import { Person } from "lemmy-js-client";
export default function isBanned(ps: Person): boolean { export default function isBanned(ps: Person): boolean {
const expires = ps.ban_expires; return ps.banned;
// Add Z to convert from UTC date
// TODO this check probably isn't necessary anymore
if (expires) {
if (ps.banned && new Date(expires + "Z") > new Date()) {
return true;
} else {
return false;
}
} else {
return ps.banned;
}
} }