forked from jsnbuchanan/crowd-funder-for-time-pwa
Remove CORS headers to enable universal image support and fix local API server settings. ## Changes **Remove CORS Headers** - Remove Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy headers - Enables images from any domain (Facebook, Medium, arbitrary websites) - Database falls back to IndexedDB mode (minimal performance impact) **Fix Local Development Configuration** - Set LOCAL_ENDORSER_API_SERVER to http://127.0.0.1:3000 (was "/api") - Create .env.development with local API server config - Fix ensureCorrectApiServer() method in HomeView.vue - "Use Local" button now sets proper localhost address **Fix Settings Cache Issues** - Add PlatformServiceMixin to AccountViewView.vue - Disable settings caching to prevent stale data - Settings changes now apply immediately without browser refresh ## Impact **Tradeoffs:** - Lost: ~2x SharedArrayBuffer database performance - Gained: Universal image support from any domain - Result: Better user experience, database still fast via IndexedDB **Files Modified:** - Configuration: vite.config.*.mts, index.html, .env.development - Source: constants/app.ts, libs/util.ts, views/*.vue, utils/PlatformServiceMixin.ts ## Rationale For a community platform, universal image support is more critical than marginal database performance gains. Users share images from arbitrary websites, making CORS restrictions incompatible with Time Safari's core mission.
77 lines
2.7 KiB
TypeScript
77 lines
2.7 KiB
TypeScript
/**
|
|
* Generic strings that could be used throughout the app.
|
|
*
|
|
* See also ../libs/veramo/setup.ts
|
|
*/
|
|
export enum AppString {
|
|
// This is used in titles and verbiage inside the app.
|
|
// There is also an app name without spaces, for packaging in the package.json file used in the manifest.
|
|
APP_NAME = "Time Safari",
|
|
APP_NAME_NO_SPACES = "TimeSafari",
|
|
|
|
PROD_ENDORSER_API_SERVER = "https://api.endorser.ch",
|
|
TEST_ENDORSER_API_SERVER = "https://test-api.endorser.ch",
|
|
LOCAL_ENDORSER_API_SERVER = "http://127.0.0.1:3000",
|
|
|
|
PROD_IMAGE_API_SERVER = "https://image-api.timesafari.app",
|
|
TEST_IMAGE_API_SERVER = "https://test-image-api.timesafari.app",
|
|
LOCAL_IMAGE_API_SERVER = "https://image-api.timesafari.app",
|
|
|
|
PROD_PARTNER_API_SERVER = "https://partner-api.endorser.ch",
|
|
TEST_PARTNER_API_SERVER = "https://test-partner-api.endorser.ch",
|
|
LOCAL_PARTNER_API_SERVER = "https://partner-api.endorser.ch",
|
|
|
|
PROD_PUSH_SERVER = "https://timesafari.app",
|
|
TEST1_PUSH_SERVER = "https://test.timesafari.app",
|
|
TEST2_PUSH_SERVER = "https://timesafari-pwa.anomalistlabs.com",
|
|
|
|
NO_CONTACT_NAME = "(no name)",
|
|
}
|
|
|
|
export const APP_SERVER =
|
|
import.meta.env.VITE_APP_SERVER || "https://timesafari.app";
|
|
|
|
export const DEFAULT_ENDORSER_API_SERVER =
|
|
import.meta.env.VITE_DEFAULT_ENDORSER_API_SERVER ||
|
|
(process.env.VITE_PLATFORM === "electron"
|
|
? AppString.PROD_ENDORSER_API_SERVER
|
|
: AppString.PROD_ENDORSER_API_SERVER);
|
|
|
|
export const DEFAULT_IMAGE_API_SERVER =
|
|
import.meta.env.VITE_DEFAULT_IMAGE_API_SERVER ||
|
|
(process.env.VITE_PLATFORM === "electron"
|
|
? AppString.PROD_IMAGE_API_SERVER
|
|
: AppString.PROD_IMAGE_API_SERVER);
|
|
|
|
export const DEFAULT_PARTNER_API_SERVER =
|
|
import.meta.env.VITE_DEFAULT_PARTNER_API_SERVER ||
|
|
(process.env.VITE_PLATFORM === "electron"
|
|
? AppString.PROD_PARTNER_API_SERVER
|
|
: AppString.PROD_PARTNER_API_SERVER);
|
|
|
|
export const DEFAULT_PUSH_SERVER =
|
|
import.meta.env.VITE_DEFAULT_PUSH_SERVER || AppString.PROD_PUSH_SERVER;
|
|
|
|
export const IMAGE_TYPE_PROFILE = "profile";
|
|
|
|
export const PASSKEYS_ENABLED =
|
|
!!import.meta.env.VITE_PASSKEYS_ENABLED || false;
|
|
|
|
/**
|
|
* The possible values for "group" and "type" are in App.vue.
|
|
* Some of this comes from the notiwind package, some is custom.
|
|
*/
|
|
export interface NotificationIface {
|
|
group: string; // "alert" | "modal"
|
|
type: string; // "toast" | "info" | "success" | "warning" | "danger"
|
|
title: string;
|
|
text?: string;
|
|
callback?: (success: boolean) => Promise<void>; // if this triggered an action
|
|
noText?: string;
|
|
onCancel?: (stopAsking?: boolean) => Promise<void>;
|
|
onNo?: (stopAsking?: boolean) => Promise<void>;
|
|
onYes?: () => Promise<void>;
|
|
promptToStopAsking?: boolean;
|
|
yesText?: string;
|
|
}
|