From e0bfc3d961ac2bc4d8a9b0623e2b6a2e9b67be81 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andr=C3=A9=20Padez?=
Date: Sat, 30 May 2026 17:07:55 +0000
Subject: [PATCH] serve static assets from local public/ instead of
static.officer.dev, simplify gmail history 404/410 handling
Co-Authored-By: Claude Opus 4.7 (1M context)
---
public/site.webmanifest | 2 +-
src/apps/landing/App.tsx | 4 ++--
src/apps/landing/DuckAvatar.tsx | 4 ++--
src/apps/landing/index.html | 10 +++++-----
.../Screens/Authentication/Layout/Background.tsx | 2 +-
.../Authentication/Layout/DuckAvatar/DuckModel.tsx | 4 ++--
.../Screens/Dashboard/Layout/Background.tsx | 2 +-
.../Screens/Dashboard/Layout/Header/Header.tsx | 2 +-
.../Settings/IntegrationsSettings/BrowserRelay.tsx | 2 +-
src/apps/officer-web/index.html | 10 +++++-----
src/server.tsx | 13 ++++++++++---
src/servers/queue/handlers/gmail-sync.ts | 9 ++-------
src/workspaces/components/Logos/DevSvgLogo.tsx | 2 +-
.../components/Logos/PastilhasSvgLogo.tsx | 4 ++--
src/workspaces/emailer/emails/UserInvite.tsx | 2 +-
.../emailer/emails/layouts/MainLayout.tsx | 2 +-
16 files changed, 38 insertions(+), 36 deletions(-)
diff --git a/public/site.webmanifest b/public/site.webmanifest
index 07871fa8..eb36d535 100644
--- a/public/site.webmanifest
+++ b/public/site.webmanifest
@@ -1 +1 @@
-{"name":"Officer Dev","short_name":"Officer","icons":[{"src":"https://static.officer.dev/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"https://static.officer.dev/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#1F2620","background_color":"#1F2620","display":"standalone"}
+{"name":"Officer Dev","short_name":"Officer","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#1F2620","background_color":"#1F2620","display":"standalone"}
diff --git a/src/apps/landing/App.tsx b/src/apps/landing/App.tsx
index 60a7a7da..3f332613 100644
--- a/src/apps/landing/App.tsx
+++ b/src/apps/landing/App.tsx
@@ -2,8 +2,8 @@ import { PixelGrid } from '../../workspaces/components/PixelGrid';
import { DuckAvatar } from './DuckAvatar';
import { WaitlistForm } from './WaitlistForm';
-const landscapeBg = 'https://static.officer.dev/landscape1.webp';
-const logoSrc = 'https://static.officer.dev/officer-logo.svg';
+const landscapeBg = '/landscape1.webp';
+const logoSrc = '/officer-logo.svg';
export const App = () => {
return (
diff --git a/src/apps/landing/DuckAvatar.tsx b/src/apps/landing/DuckAvatar.tsx
index e9ddb3f7..6e27d5dc 100644
--- a/src/apps/landing/DuckAvatar.tsx
+++ b/src/apps/landing/DuckAvatar.tsx
@@ -3,8 +3,8 @@ import { OrbitControls, useGLTF, useAnimations } from '@react-three/drei';
import { useEffect, useState, useRef } from 'react';
function DuckModel({ onLoaded }: { onLoaded: () => void }) {
- const character = useGLTF('https://static.officer.dev/duck3D/Character_output.glb');
- const animations = useGLTF('https://static.officer.dev/duck3D/Meshy_Merged_Animations.glb');
+ const character = useGLTF('/duck3D/Character_output.glb');
+ const animations = useGLTF('/duck3D/Meshy_Merged_Animations.glb');
const meshRef = useRef(null);
const { actions } = useAnimations(animations.animations, meshRef);
diff --git a/src/apps/landing/index.html b/src/apps/landing/index.html
index effdd9b3..e8a8172d 100644
--- a/src/apps/landing/index.html
+++ b/src/apps/landing/index.html
@@ -11,7 +11,7 @@
-
+
@@ -25,10 +25,10 @@
-
-
-
-
+
+
+
+
diff --git a/src/apps/officer-web/Screens/Authentication/Layout/Background.tsx b/src/apps/officer-web/Screens/Authentication/Layout/Background.tsx
index 75e0ca9d..1739122c 100644
--- a/src/apps/officer-web/Screens/Authentication/Layout/Background.tsx
+++ b/src/apps/officer-web/Screens/Authentication/Layout/Background.tsx
@@ -1,7 +1,7 @@
import { DuckAvatar } from "./DuckAvatar";
import { PixelGrid } from "@/components/PixelGrid";
import { useGlobal } from 'hooks/useGlobal';
-const landscapebg = 'https://static.officer.dev/landscape1.webp';
+const landscapebg = '/landscape1.webp';
export function Background() {
const [duckHidden] = useGlobal('DUCK_HIDDEN', false);
diff --git a/src/apps/officer-web/Screens/Authentication/Layout/DuckAvatar/DuckModel.tsx b/src/apps/officer-web/Screens/Authentication/Layout/DuckAvatar/DuckModel.tsx
index 9cf33945..788c74a5 100644
--- a/src/apps/officer-web/Screens/Authentication/Layout/DuckAvatar/DuckModel.tsx
+++ b/src/apps/officer-web/Screens/Authentication/Layout/DuckAvatar/DuckModel.tsx
@@ -8,8 +8,8 @@ type DuckModelProps = {
};
export function DuckModel({ onUpdate, onAssetsLoaded, currentSection }: DuckModelProps) {
- const character = useGLTF('https://static.officer.dev/duck3D/Character_output.glb');
- const animations = useGLTF('https://static.officer.dev/duck3D/Meshy_Merged_Animations.glb');
+ const character = useGLTF('/duck3D/Character_output.glb');
+ const animations = useGLTF('/duck3D/Meshy_Merged_Animations.glb');
const meshRef = useRef(null);
const { actions } = useAnimations(animations.animations, meshRef);
diff --git a/src/apps/officer-web/Screens/Dashboard/Layout/Background.tsx b/src/apps/officer-web/Screens/Dashboard/Layout/Background.tsx
index e60fd821..687ca8e2 100644
--- a/src/apps/officer-web/Screens/Dashboard/Layout/Background.tsx
+++ b/src/apps/officer-web/Screens/Dashboard/Layout/Background.tsx
@@ -1,5 +1,5 @@
import { PixelGrid } from "@/components/PixelGrid";
-const landscapebg = 'https://static.officer.dev/landscape1.webp';
+const landscapebg = '/landscape1.webp';
export function Background() {
return (
diff --git a/src/apps/officer-web/Screens/Dashboard/Layout/Header/Header.tsx b/src/apps/officer-web/Screens/Dashboard/Layout/Header/Header.tsx
index 0f8849cf..871de60c 100644
--- a/src/apps/officer-web/Screens/Dashboard/Layout/Header/Header.tsx
+++ b/src/apps/officer-web/Screens/Dashboard/Layout/Header/Header.tsx
@@ -32,7 +32,7 @@ export function Header({ dockItems }: HeaderProps) {
)}
{
Download and unzip the extension, then load it in Chrome:
diff --git a/src/apps/officer-web/index.html b/src/apps/officer-web/index.html
index 5e135a2d..e1d874ba 100644
--- a/src/apps/officer-web/index.html
+++ b/src/apps/officer-web/index.html
@@ -11,7 +11,7 @@
-
+
@@ -25,10 +25,10 @@
-
-
-
-
+
+
+
+
diff --git a/src/server.tsx b/src/server.tsx
index de57cb92..e9ea1862 100644
--- a/src/server.tsx
+++ b/src/server.tsx
@@ -20,6 +20,13 @@ import { toShellUsername } from './servers/data-path';
const { PORT = '5000' } = process.env;
+// Build static file routes from public/
+const publicRoutes: Record Response> = {};
+for await (const file of new Bun.Glob('**').scan({ cwd: './public' })) {
+ const bunFile = Bun.file(`./public/${file}`);
+ publicRoutes[`/${file}`] = () => new Response(bunFile);
+}
+
type WSData = {
userId: number;
email: string;
@@ -256,14 +263,14 @@ const server = serve({
idleTimeout: 60,
maxRequestBodySize: 1024 * 1024 * 1024 * 50, // 50 GB
routes: {
- '/og-image.jpg': () => new Response(Bun.file('public/og-image.jpg'), { headers: { 'Content-Type': 'image/jpeg' } }),
+ ...publicRoutes,
'/novnc/*': (req) => {
const file = Bun.file(`public${new URL(req.url).pathname}`);
- return new Response(file, { headers: { 'Content-Type': 'application/javascript' } });
+ return new Response(file);
},
'/vendor/*': (req) => {
const file = Bun.file(`public${new URL(req.url).pathname}`);
- return new Response(file, { headers: { 'Content-Type': 'application/javascript' } });
+ return new Response(file);
},
'/api/dev-server-proxy/*': (req, server) => {
if (req.headers.get('upgrade') === 'websocket') return upgradeDevServerWs(req, server);
diff --git a/src/servers/queue/handlers/gmail-sync.ts b/src/servers/queue/handlers/gmail-sync.ts
index 9938c0d4..139980d3 100644
--- a/src/servers/queue/handlers/gmail-sync.ts
+++ b/src/servers/queue/handlers/gmail-sync.ts
@@ -142,13 +142,8 @@ async function getHistoryChanges(
const res = await gmailApiFetch(accessToken, '/history', params);
- if (res.status === 404) {
- // No history — nothing new
- return { messageIds: [], historyId: latestHistoryId };
- }
-
- if (res.status === 410) {
- // historyId too old — caller should fall back to date-based listing
+ if (res.status === 404 || res.status === 410) {
+ // historyId too old or invalid — caller should fall back to date-based listing
throw new HistoryExpiredError();
}
diff --git a/src/workspaces/components/Logos/DevSvgLogo.tsx b/src/workspaces/components/Logos/DevSvgLogo.tsx
index ba74fd07..b9fdf61c 100644
--- a/src/workspaces/components/Logos/DevSvgLogo.tsx
+++ b/src/workspaces/components/Logos/DevSvgLogo.tsx
@@ -7,7 +7,7 @@ export function OfficerIconLogo({ size = 'xl' }: SvgLogoProps) {
return (
diff --git a/src/workspaces/components/Logos/PastilhasSvgLogo.tsx b/src/workspaces/components/Logos/PastilhasSvgLogo.tsx
index e8c00044..e9480f94 100644
--- a/src/workspaces/components/Logos/PastilhasSvgLogo.tsx
+++ b/src/workspaces/components/Logos/PastilhasSvgLogo.tsx
@@ -16,7 +16,7 @@ export function OfficerSvgLogoRegular({ size = 'xl' }: SvgLogoProps) {
return (
@@ -28,7 +28,7 @@ export function OfficerSvgLogoSquare({ size = 'xl' }: SvgLogoProps) {
return (
diff --git a/src/workspaces/emailer/emails/UserInvite.tsx b/src/workspaces/emailer/emails/UserInvite.tsx
index dde700b5..8ef5d6ce 100644
--- a/src/workspaces/emailer/emails/UserInvite.tsx
+++ b/src/workspaces/emailer/emails/UserInvite.tsx
@@ -15,7 +15,7 @@ const Email = ({ invitedBy, url }: EmailProps) => {
diff --git a/src/workspaces/emailer/emails/layouts/MainLayout.tsx b/src/workspaces/emailer/emails/layouts/MainLayout.tsx
index cf071b30..0d00fe87 100644
--- a/src/workspaces/emailer/emails/layouts/MainLayout.tsx
+++ b/src/workspaces/emailer/emails/layouts/MainLayout.tsx
@@ -10,7 +10,7 @@ const MainLayout = ({ children }: { children: ReactNode }) => {