Redirect to login when groups or accounts 403
This commit is contained in:
parent
5ffaaa4c3a
commit
bcac58b9c3
7 changed files with 68 additions and 10 deletions
|
@ -1,3 +1,6 @@
|
|||
import { useEffect } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
import { Entities } from 'soapbox/entity-store/entities';
|
||||
import { useEntity } from 'soapbox/entity-store/hooks';
|
||||
import { useFeatures, useLoggedIn } from 'soapbox/hooks';
|
||||
|
@ -12,11 +15,12 @@ interface UseAccountOpts {
|
|||
|
||||
function useAccount(accountId?: string, opts: UseAccountOpts = {}) {
|
||||
const api = useApi();
|
||||
const history = useHistory();
|
||||
const features = useFeatures();
|
||||
const { me } = useLoggedIn();
|
||||
const { withRelationship } = opts;
|
||||
|
||||
const { entity: account, ...result } = useEntity<Account>(
|
||||
const { entity: account, isUnauthorized, ...result } = useEntity<Account>(
|
||||
[Entities.ACCOUNTS, accountId!],
|
||||
() => api.get(`/api/v1/accounts/${accountId}`),
|
||||
{ schema: accountSchema, enabled: !!accountId },
|
||||
|
@ -30,10 +34,17 @@ function useAccount(accountId?: string, opts: UseAccountOpts = {}) {
|
|||
const isBlocked = account?.relationship?.blocked_by === true;
|
||||
const isUnavailable = (me === account?.id) ? false : (isBlocked && !features.blockersVisible);
|
||||
|
||||
useEffect(() => {
|
||||
if (isUnauthorized) {
|
||||
history.push('/login');
|
||||
}
|
||||
}, [isUnauthorized]);
|
||||
|
||||
return {
|
||||
...result,
|
||||
isLoading: result.isLoading,
|
||||
isRelationshipLoading,
|
||||
isUnauthorized,
|
||||
isUnavailable,
|
||||
account: account ? { ...account, relationship } : undefined,
|
||||
};
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
import { useEffect } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
import { Entities } from 'soapbox/entity-store/entities';
|
||||
import { useEntityLookup } from 'soapbox/entity-store/hooks';
|
||||
import { useFeatures, useLoggedIn } from 'soapbox/hooks';
|
||||
|
@ -13,10 +16,11 @@ interface UseAccountLookupOpts {
|
|||
function useAccountLookup(acct: string | undefined, opts: UseAccountLookupOpts = {}) {
|
||||
const api = useApi();
|
||||
const features = useFeatures();
|
||||
const history = useHistory();
|
||||
const { me } = useLoggedIn();
|
||||
const { withRelationship } = opts;
|
||||
|
||||
const { entity: account, ...result } = useEntityLookup<Account>(
|
||||
const { entity: account, isUnauthorized, ...result } = useEntityLookup<Account>(
|
||||
Entities.ACCOUNTS,
|
||||
(account) => account.acct === acct,
|
||||
() => api.get(`/api/v1/accounts/lookup?acct=${acct}`),
|
||||
|
@ -31,10 +35,17 @@ function useAccountLookup(acct: string | undefined, opts: UseAccountLookupOpts =
|
|||
const isBlocked = account?.relationship?.blocked_by === true;
|
||||
const isUnavailable = (me === account?.id) ? false : (isBlocked && !features.blockersVisible);
|
||||
|
||||
useEffect(() => {
|
||||
if (isUnauthorized) {
|
||||
history.push('/login');
|
||||
}
|
||||
}, [isUnauthorized]);
|
||||
|
||||
return {
|
||||
...result,
|
||||
isLoading: result.isLoading,
|
||||
isRelationshipLoading,
|
||||
isUnauthorized,
|
||||
isUnavailable,
|
||||
account: account ? { ...account, relationship } : undefined,
|
||||
};
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
import { useEffect } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
import { Entities } from 'soapbox/entity-store/entities';
|
||||
import { useEntity } from 'soapbox/entity-store/hooks';
|
||||
import { useApi } from 'soapbox/hooks';
|
||||
|
@ -7,8 +10,9 @@ import { useGroupRelationship } from './useGroupRelationship';
|
|||
|
||||
function useGroup(groupId: string, refetch = true) {
|
||||
const api = useApi();
|
||||
const history = useHistory();
|
||||
|
||||
const { entity: group, ...result } = useEntity<Group>(
|
||||
const { entity: group, isUnauthorized, ...result } = useEntity<Group>(
|
||||
[Entities.GROUPS, groupId],
|
||||
() => api.get(`/api/v1/groups/${groupId}`),
|
||||
{
|
||||
|
@ -19,8 +23,15 @@ function useGroup(groupId: string, refetch = true) {
|
|||
);
|
||||
const { groupRelationship: relationship } = useGroupRelationship(groupId);
|
||||
|
||||
useEffect(() => {
|
||||
if (isUnauthorized) {
|
||||
history.push('/login');
|
||||
}
|
||||
}, [isUnauthorized]);
|
||||
|
||||
return {
|
||||
...result,
|
||||
isUnauthorized,
|
||||
group: group ? { ...group, relationship: relationship || null } : undefined,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,24 +1,37 @@
|
|||
import { useEffect } from 'react';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
|
||||
import { Entities } from 'soapbox/entity-store/entities';
|
||||
import { useEntityLookup } from 'soapbox/entity-store/hooks';
|
||||
import { useApi } from 'soapbox/hooks/useApi';
|
||||
import { useFeatures } from 'soapbox/hooks/useFeatures';
|
||||
import { groupSchema } from 'soapbox/schemas';
|
||||
|
||||
import { useGroupRelationship } from './useGroupRelationship';
|
||||
|
||||
function useGroupLookup(slug: string) {
|
||||
const api = useApi();
|
||||
const features = useFeatures();
|
||||
const history = useHistory();
|
||||
|
||||
const { entity: group, ...result } = useEntityLookup(
|
||||
const { entity: group, isUnauthorized, ...result } = useEntityLookup(
|
||||
Entities.GROUPS,
|
||||
(group) => group.slug === slug,
|
||||
() => api.get(`/api/v1/groups/lookup?name=${slug}`),
|
||||
{ schema: groupSchema, enabled: !!slug },
|
||||
{ schema: groupSchema, enabled: features.groups && !!slug },
|
||||
);
|
||||
|
||||
const { groupRelationship: relationship } = useGroupRelationship(group?.id);
|
||||
|
||||
useEffect(() => {
|
||||
if (isUnauthorized) {
|
||||
history.push('/login');
|
||||
}
|
||||
}, [isUnauthorized]);
|
||||
|
||||
return {
|
||||
...result,
|
||||
isUnauthorized,
|
||||
entity: group ? { ...group, relationship: relationship || null } : undefined,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { useEffect } from 'react';
|
||||
import { AxiosError } from 'axios';
|
||||
import { useEffect, useState } from 'react';
|
||||
import z from 'zod';
|
||||
|
||||
import { useAppDispatch, useAppSelector, useLoading } from 'soapbox/hooks';
|
||||
|
@ -24,6 +25,8 @@ function useEntity<TEntity extends Entity>(
|
|||
opts: UseEntityOpts<TEntity> = {},
|
||||
) {
|
||||
const [isFetching, setPromise] = useLoading(true);
|
||||
const [error, setError] = useState<unknown>();
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const [entityType, entityId] = path;
|
||||
|
@ -35,6 +38,7 @@ function useEntity<TEntity extends Entity>(
|
|||
|
||||
const isEnabled = opts.enabled ?? true;
|
||||
const isLoading = isFetching && !entity;
|
||||
const isLoaded = !isFetching && !!entity;
|
||||
|
||||
const fetchEntity = async () => {
|
||||
try {
|
||||
|
@ -42,7 +46,7 @@ function useEntity<TEntity extends Entity>(
|
|||
const entity = schema.parse(response.data);
|
||||
dispatch(importEntities([entity], entityType));
|
||||
} catch (e) {
|
||||
// do nothing
|
||||
setError(e);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -58,6 +62,10 @@ function useEntity<TEntity extends Entity>(
|
|||
fetchEntity,
|
||||
isFetching,
|
||||
isLoading,
|
||||
isLoaded,
|
||||
error,
|
||||
isUnauthorized: error instanceof AxiosError && error.response?.status === 401,
|
||||
isForbidden: error instanceof AxiosError && error.response?.status === 403,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { useEffect } from 'react';
|
||||
import { AxiosError } from 'axios';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { useAppDispatch, useAppSelector, useLoading } from 'soapbox/hooks';
|
||||
|
@ -23,6 +24,7 @@ function useEntityLookup<TEntity extends Entity>(
|
|||
|
||||
const dispatch = useAppDispatch();
|
||||
const [isFetching, setPromise] = useLoading(true);
|
||||
const [error, setError] = useState<unknown>();
|
||||
|
||||
const entity = useAppSelector(state => findEntity(state, entityType, lookupFn));
|
||||
const isEnabled = opts.enabled ?? true;
|
||||
|
@ -34,7 +36,7 @@ function useEntityLookup<TEntity extends Entity>(
|
|||
const entity = schema.parse(response.data);
|
||||
dispatch(importEntities([entity], entityType));
|
||||
} catch (e) {
|
||||
// do nothing
|
||||
setError(e);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -51,6 +53,8 @@ function useEntityLookup<TEntity extends Entity>(
|
|||
fetchEntity,
|
||||
isFetching,
|
||||
isLoading,
|
||||
isUnauthorized: error instanceof AxiosError && error.response?.status === 401,
|
||||
isForbidden: error instanceof AxiosError && error.response?.status === 403,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -327,7 +327,7 @@ const SwitchingColumnsArea: React.FC<ISwitchingColumnsArea> = ({ children }) =>
|
|||
|
||||
{features.groupsTags && <WrappedRoute path='/group/:groupSlug/tags' exact page={GroupPage} component={GroupTagsSlug} content={children} />}
|
||||
{features.groupsTags && <WrappedRoute path='/group/:groupSlug/tag/:tagId' exact page={GroupsPendingPage} component={GroupTagTimelineSlug} content={children} />}
|
||||
{features.groups && <WrappedRoute path='/group/:groupSlug' exact page={GroupPage} component={GroupTimelineSlug} content={children} />}
|
||||
{features.groups && <WrappedRoute path='/group/:groupSlug' publicRoute exact page={GroupPage} component={GroupTimelineSlug} content={children} />}
|
||||
{features.groups && <WrappedRoute path='/group/:groupSlug/members' exact page={GroupPage} component={GroupMembersSlug} content={children} />}
|
||||
{features.groups && <WrappedRoute path='/group/:groupSlug/media' publicRoute={!authenticatedProfile} component={GroupGallerySlug} page={GroupPage} content={children} />}
|
||||
{features.groups && <WrappedRoute path='/group/:groupSlug/manage' exact page={ManageGroupsPage} component={ManageGroupSlug} content={children} />}
|
||||
|
|
Loading…
Reference in a new issue