Remove public api endpoint
This commit is contained in:
parent
534348b7a8
commit
4dc9149931
@ -158,8 +158,7 @@ Application behavior can be changed by configuring the following environment var
|
||||
#### Settings
|
||||
- `NEXT_PUBLIC_GEO_PRIVACY = 1` disables collection/display of location-based data (⚠️ re-compresses uploaded images in order to remove GPS information)
|
||||
- `NEXT_PUBLIC_ALLOW_PUBLIC_DOWNLOADS = 1` enables public photo downloads for all visitors (⚠️ may result in increased bandwidth usage)
|
||||
- `NEXT_PUBLIC_PUBLIC_FEED = 1` enables public feed available at `/feed.json` and `/rss.xml`
|
||||
- `NEXT_PUBLIC_PUBLIC_API = 1` enables public API available at `/api`
|
||||
- `NEXT_PUBLIC_SITE_FEEDS = 1` enables feeds at `/feed.json` and `/rss.xml`
|
||||
- `NEXT_PUBLIC_IGNORE_PRIORITY_ORDER = 1` prevents `priority_order` field affecting photo order
|
||||
- `NEXT_PUBLIC_OG_TEXT_ALIGNMENT = BOTTOM` keeps OG image text bottom aligned (default is top)
|
||||
|
||||
|
||||
@ -1,24 +0,0 @@
|
||||
import { getPhotosCached } from '@/photo/cache';
|
||||
import { API_PHOTO_REQUEST_LIMIT, formatPhotoForApi } from '@/app/api';
|
||||
import {
|
||||
BASE_URL,
|
||||
PUBLIC_API_ENABLED,
|
||||
META_TITLE,
|
||||
} from '@/app/config';
|
||||
|
||||
export const dynamic = 'force-dynamic';
|
||||
|
||||
export async function GET() {
|
||||
if (PUBLIC_API_ENABLED) {
|
||||
const photos = await getPhotosCached({ limit: API_PHOTO_REQUEST_LIMIT });
|
||||
return Response.json({
|
||||
meta: {
|
||||
title: META_TITLE,
|
||||
url: BASE_URL,
|
||||
},
|
||||
photos: photos.map(formatPhotoForApi),
|
||||
});
|
||||
} else {
|
||||
return new Response('API access disabled', { status: 404 });
|
||||
}
|
||||
}
|
||||
@ -1,18 +1,17 @@
|
||||
import { getPhotosCached } from '@/photo/cache';
|
||||
import { INFINITE_SCROLL_FEED_INITIAL } from '@/photo';
|
||||
import {
|
||||
BASE_URL,
|
||||
PUBLIC_FEED_ENABLED,
|
||||
SITE_FEEDS_ENABLED,
|
||||
META_TITLE,
|
||||
} from '@/app/config';
|
||||
import { formatPhotoForFeedJson } from '@/app/feed';
|
||||
import { FEED_PHOTO_REQUEST_LIMIT, formatPhotoForFeedJson } from '@/app/feed';
|
||||
|
||||
export const dynamic = 'force-static';
|
||||
|
||||
export async function GET() {
|
||||
if (PUBLIC_FEED_ENABLED) {
|
||||
if (SITE_FEEDS_ENABLED) {
|
||||
const photos = await getPhotosCached({
|
||||
limit: INFINITE_SCROLL_FEED_INITIAL,
|
||||
limit: FEED_PHOTO_REQUEST_LIMIT,
|
||||
sortBy: 'createdAt',
|
||||
});
|
||||
return Response.json({
|
||||
|
||||
@ -10,7 +10,7 @@ import {
|
||||
META_TITLE,
|
||||
HTML_LANG,
|
||||
NAV_CAPTION,
|
||||
PUBLIC_FEED_ENABLED,
|
||||
SITE_FEEDS_ENABLED,
|
||||
} from '@/app/config';
|
||||
import AppStateProvider from '@/state/AppStateProvider';
|
||||
import ToasterWithThemes from '@/toast/ToasterWithThemes';
|
||||
@ -66,7 +66,7 @@ export const metadata: Metadata = {
|
||||
type: 'image/png',
|
||||
sizes: '180x180',
|
||||
}],
|
||||
...PUBLIC_FEED_ENABLED && {
|
||||
...SITE_FEEDS_ENABLED && {
|
||||
alternates: {
|
||||
types: {
|
||||
'application/rss+xml': '/rss.xml',
|
||||
|
||||
@ -4,14 +4,15 @@ import {
|
||||
BASE_URL,
|
||||
META_DESCRIPTION,
|
||||
META_TITLE,
|
||||
PUBLIC_FEED_ENABLED,
|
||||
SITE_FEEDS_ENABLED,
|
||||
} from '@/app/config';
|
||||
import { feedPhotoToXml, formatPhotoForFeedRss } from '@/app/feed';
|
||||
import { ABSOLUTE_PATH_FOR_FEED_JSON } from '@/app/paths';
|
||||
|
||||
export const dynamic = 'force-static';
|
||||
|
||||
export async function GET() {
|
||||
if (PUBLIC_FEED_ENABLED) {
|
||||
if (SITE_FEEDS_ENABLED) {
|
||||
const photos = await getPhotosCached({
|
||||
limit: INFINITE_SCROLL_FEED_INITIAL,
|
||||
sortBy: 'createdAt',
|
||||
@ -26,13 +27,11 @@ export async function GET() {
|
||||
|
||||
<channel>
|
||||
<title>${META_TITLE}</title>
|
||||
<atom:link href="${BASE_URL}/rss.xml"
|
||||
<atom:link href="${ABSOLUTE_PATH_FOR_FEED_JSON}"
|
||||
rel="self" type="application/rss+xml" />
|
||||
<link>${BASE_URL}</link>
|
||||
<description>${META_DESCRIPTION}</description>
|
||||
|
||||
${items.join('\n\n ')}
|
||||
|
||||
${items.join('\n')}
|
||||
</channel>
|
||||
|
||||
</rss>`,
|
||||
|
||||
@ -31,6 +31,8 @@ import ScoreCardContainer from '@/components/ScoreCardContainer';
|
||||
import { DEFAULT_CATEGORY_KEYS, getHiddenCategories } from '@/category';
|
||||
import { AI_AUTO_GENERATED_FIELDS_ALL } from '@/photo/ai';
|
||||
import clsx from 'clsx/lite';
|
||||
import Link from 'next/link';
|
||||
import { PATH_FEED_JSON, PATH_RSS_XML } from '@/app/paths';
|
||||
|
||||
export default function AdminAppConfigurationClient({
|
||||
// Storage
|
||||
@ -103,8 +105,7 @@ export default function AdminAppConfigurationClient({
|
||||
// Settings
|
||||
isGeoPrivacyEnabled,
|
||||
arePublicDownloadsEnabled,
|
||||
isPublicApiEnabled,
|
||||
isPublicFeedEnabled,
|
||||
areSiteFeedsEnabled,
|
||||
isPriorityOrderEnabled,
|
||||
isOgTextBottomAligned,
|
||||
// Internal
|
||||
@ -178,6 +179,15 @@ export default function AdminAppConfigurationClient({
|
||||
{message}
|
||||
</ErrorNote>;
|
||||
|
||||
const renderLink = (href: string, children?: ReactNode) =>
|
||||
<Link
|
||||
href={href}
|
||||
className="underline underline-offset-3 hover:no-underline"
|
||||
target="_blank"
|
||||
>
|
||||
{children || href}
|
||||
</Link>;
|
||||
|
||||
return (
|
||||
<ScoreCardContainer>
|
||||
<ChecklistGroup
|
||||
@ -735,23 +745,14 @@ export default function AdminAppConfigurationClient({
|
||||
{renderEnvVars(['NEXT_PUBLIC_ALLOW_PUBLIC_DOWNLOADS'])}
|
||||
</ChecklistRow>
|
||||
<ChecklistRow
|
||||
title="Public Feed"
|
||||
status={isPublicFeedEnabled}
|
||||
title="Site feeds (JSON/RSS)"
|
||||
status={areSiteFeedsEnabled}
|
||||
optional
|
||||
>
|
||||
Set environment variable to {'"1"'} to enable
|
||||
a public feed available at <code>/feed.json</code>
|
||||
and <code>/rss.xml</code>:
|
||||
{renderEnvVars(['NEXT_PUBLIC_PUBLIC_FEED'])}
|
||||
</ChecklistRow>
|
||||
<ChecklistRow
|
||||
title="Public API"
|
||||
status={isPublicApiEnabled}
|
||||
optional
|
||||
>
|
||||
Set environment variable to {'"1"'} to enable
|
||||
a public API available at <code>/api</code>:
|
||||
{renderEnvVars(['NEXT_PUBLIC_PUBLIC_API'])}
|
||||
Set environment variable to {'"1"'} to enable feeds at
|
||||
{' '}
|
||||
{renderLink(PATH_FEED_JSON)} and {renderLink(PATH_RSS_XML)}:
|
||||
{renderEnvVars(['NEXT_PUBLIC_SITE_FEEDS'])}
|
||||
</ChecklistRow>
|
||||
<ChecklistRow
|
||||
title="Priority order"
|
||||
|
||||
@ -1,43 +0,0 @@
|
||||
import { Photo } from '@/photo';
|
||||
import { absolutePathForPhoto } from './paths';
|
||||
import { formatDateFromPostgresString } from '@/utility/date';
|
||||
import { getNextImageUrlForRequest } from '@/platforms/next-image';
|
||||
|
||||
export const API_PHOTO_REQUEST_LIMIT = 40;
|
||||
|
||||
export interface PublicApi {
|
||||
meta: {
|
||||
title: string
|
||||
url: string
|
||||
}
|
||||
photos: PublicApiPhoto[]
|
||||
}
|
||||
|
||||
interface PublicApiPhoto {
|
||||
id: string
|
||||
title?: string
|
||||
url: string
|
||||
make?: string
|
||||
model?: string
|
||||
tags?: string[]
|
||||
takenAtNaive: string
|
||||
src: Record<
|
||||
'small' | 'medium' | 'large',
|
||||
string
|
||||
>
|
||||
}
|
||||
|
||||
export const formatPhotoForApi = (photo: Photo): PublicApiPhoto => ({
|
||||
id: photo.id,
|
||||
title: photo.title,
|
||||
url: absolutePathForPhoto({ photo }),
|
||||
...photo.make && { make: photo.make },
|
||||
...photo.model && { model: photo.model },
|
||||
...photo.tags.length > 0 && { tags: photo.tags },
|
||||
takenAtNaive: formatDateFromPostgresString(photo.takenAtNaive),
|
||||
src: {
|
||||
small: getNextImageUrlForRequest({ imageUrl: photo.url, size: 200 }),
|
||||
medium: getNextImageUrlForRequest({ imageUrl: photo.url, size: 640 }),
|
||||
large: getNextImageUrlForRequest({ imageUrl: photo.url, size: 1200 }),
|
||||
},
|
||||
});
|
||||
@ -307,10 +307,8 @@ export const GEO_PRIVACY_ENABLED =
|
||||
process.env.NEXT_PUBLIC_GEO_PRIVACY === '1';
|
||||
export const ALLOW_PUBLIC_DOWNLOADS =
|
||||
process.env.NEXT_PUBLIC_ALLOW_PUBLIC_DOWNLOADS === '1';
|
||||
export const PUBLIC_FEED_ENABLED =
|
||||
process.env.NEXT_PUBLIC_PUBLIC_FEED === '1';
|
||||
export const PUBLIC_API_ENABLED =
|
||||
process.env.NEXT_PUBLIC_PUBLIC_API === '1';
|
||||
export const SITE_FEEDS_ENABLED =
|
||||
process.env.NEXT_PUBLIC_SITE_FEEDS === '1';
|
||||
export const PRIORITY_ORDER_ENABLED =
|
||||
process.env.NEXT_PUBLIC_IGNORE_PRIORITY_ORDER !== '1';
|
||||
export const OG_TEXT_BOTTOM_ALIGNMENT =
|
||||
@ -419,8 +417,7 @@ export const APP_CONFIGURATION = {
|
||||
// Settings
|
||||
isGeoPrivacyEnabled: GEO_PRIVACY_ENABLED,
|
||||
arePublicDownloadsEnabled: ALLOW_PUBLIC_DOWNLOADS,
|
||||
isPublicApiEnabled: PUBLIC_API_ENABLED,
|
||||
isPublicFeedEnabled: PUBLIC_FEED_ENABLED,
|
||||
areSiteFeedsEnabled: SITE_FEEDS_ENABLED,
|
||||
isPriorityOrderEnabled: PRIORITY_ORDER_ENABLED,
|
||||
isOgTextBottomAligned: OG_TEXT_BOTTOM_ALIGNMENT,
|
||||
// Internal
|
||||
|
||||
@ -6,7 +6,7 @@ import {
|
||||
} from '@/platforms/next-image';
|
||||
import { formatDate, formatDateFromPostgresString } from '@/utility/date';
|
||||
|
||||
export const API_PHOTO_REQUEST_LIMIT = 40;
|
||||
export const FEED_PHOTO_REQUEST_LIMIT = 40;
|
||||
|
||||
export const FEED_PHOTO_WIDTH_SMALL = 200;
|
||||
export const FEED_PHOTO_WIDTH_MEDIUM = 640;
|
||||
|
||||
@ -15,6 +15,10 @@ export const PATH_API = '/api';
|
||||
export const PATH_SIGN_IN = '/sign-in';
|
||||
export const PATH_OG = '/og';
|
||||
|
||||
// Feeds
|
||||
export const PATH_FEED_JSON = '/feed.json';
|
||||
export const PATH_RSS_XML = '/rss.xml';
|
||||
|
||||
export const PATH_GRID_INFERRED = GRID_HOMEPAGE_ENABLED
|
||||
? PATH_ROOT
|
||||
: PATH_GRID;
|
||||
@ -167,6 +171,12 @@ export const pathForRecipe = (recipe: string) =>
|
||||
`${PREFIX_RECIPE}/${recipe}`;
|
||||
|
||||
// Absolute paths
|
||||
export const ABSOLUTE_PATH_FOR_FEED_JSON =
|
||||
`${getBaseUrl()}${PATH_FEED_JSON}`;
|
||||
|
||||
export const ABSOLUTE_PATH_FOR_RSS_XML =
|
||||
`${getBaseUrl()}${PATH_RSS_XML}`;
|
||||
|
||||
export const ABSOLUTE_PATH_FOR_HOME_IMAGE =
|
||||
`${getBaseUrl()}/home-image`;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user