serve api on same origin at /api

This commit is contained in:
2025-10-29 01:52:48 +01:00
parent 3bdca88144
commit 0052dff119
8 changed files with 71 additions and 56 deletions
-1
View File
@@ -6,7 +6,6 @@
<title>Papercrate</title>
</head>
<body>
<script src="/config.js"></script>
<main id="app"></main>
</body>
</html>
+29 -24
View File
@@ -36,33 +36,28 @@ import { createPreviewSurface } from './preview/PreviewWorkspace';
import { createDesktopSurface } from './DesktopWorkspace';
import { AppShellContext, useAppShell } from './appShellContext';
const runtimeApiBase =
typeof window !== 'undefined' && window.__PAPERCRATE_API_BASE_URL
? window.__PAPERCRATE_API_BASE_URL
: '';
const DEFAULT_DEV_API = 'http://127.0.0.1:3000';
const ASSET_PRESIGN_TTL_MS = 240 * 1000; // backend issues 5 min tokens; refresh slightly early
const TAG_MIME_TYPES = ['application/x-papercrate-tag', 'text/papercrate-tag'];
const API_ROOT = (runtimeApiBase || process.env.API_BASE_URL || DEFAULT_DEV_API).replace(/\/$/, '');
const api = axios.create({
baseURL: API_ROOT ? `${API_ROOT}/api` : '/api',
baseURL: '/api',
withCredentials: true,
});
const STORED_TOKEN = window.localStorage.getItem('papercrate_token') || '';
const storage = typeof window !== 'undefined' ? window.sessionStorage : undefined;
const STORED_TOKEN = storage?.getItem('papercrate_token') || '';
let STORED_TENANT = null;
try {
const rawTenant = window.localStorage.getItem('papercrate_tenant');
if (rawTenant) {
STORED_TENANT = JSON.parse(rawTenant);
}
} catch (
// eslint-disable-next-line no-empty
error
) {}
if (storage) {
try {
const rawTenant = storage.getItem('papercrate_tenant');
if (rawTenant) {
STORED_TENANT = JSON.parse(rawTenant);
}
} catch (
// eslint-disable-next-line no-empty
error
) {}
}
if (STORED_TOKEN) {
api.defaults.headers.common.Authorization = `Bearer ${STORED_TOKEN}`;
}
@@ -191,22 +186,22 @@ const AppStateProvider = ({ children }) => {
const token = state.token || '';
if (token) {
api.defaults.headers.common.Authorization = `Bearer ${token}`;
window.localStorage.setItem('papercrate_token', token);
storage?.setItem('papercrate_token', token);
} else {
delete api.defaults.headers.common.Authorization;
window.localStorage.removeItem('papercrate_token');
storage?.removeItem('papercrate_token');
}
}, [state.token]);
useEffect(() => {
if (state.tenant) {
try {
window.localStorage.setItem('papercrate_tenant', JSON.stringify(state.tenant));
storage?.setItem('papercrate_tenant', JSON.stringify(state.tenant));
} catch (error) {
console.warn('Failed to persist tenant info', error);
}
} else {
window.localStorage.removeItem('papercrate_tenant');
storage?.removeItem('papercrate_tenant');
}
}, [state.tenant]);
@@ -270,7 +265,7 @@ const ROW_KEY_SEPARATOR = ':';
const DOCUMENT_ROW_PREFIX = 'document';
const FOLDER_ROW_PREFIX = 'folder';
const resolveApiPath = (path = '') => (API_ROOT ? `${API_ROOT}${path}` : path);
const resolveApiPath = (path = '') => path;
const makeRowKey = (type, id) =>
id ? `${type}${ROW_KEY_SEPARATOR}${id}` : `${type}${ROW_KEY_SEPARATOR}`;
@@ -571,6 +566,16 @@ const AppLayout = () => {
});
}, []);
const initialRefreshAttemptedRef = useRef(Boolean(token));
useEffect(() => {
if (!token && !initialRefreshAttemptedRef.current && appStatus === 'logged-out') {
initialRefreshAttemptedRef.current = true;
console.log('[Auth] Attempting refresh at startup');
refreshAccessToken().catch(() => {});
}
}, [token, appStatus, refreshAccessToken]);
const clearFilters = useCallback(() => {
setSearchQuery('');
setActiveTagFilters([]);