web: guard invalid VAPID key during push subscription
Some checks failed
Android CI / android (push) Has started running
Android Release / release (push) Has been cancelled
CI / test (push) Has been cancelled

This commit is contained in:
Codex
2026-03-10 00:35:06 +03:00
parent 158126555c
commit 148870de14

View File

@@ -9,7 +9,7 @@ let foregroundListenerAttached = false;
export async function ensureWebPushRegistration(): Promise<void> {
const config = getFirebaseConfig();
const vapidKey = import.meta.env.VITE_FIREBASE_VAPID_KEY?.trim();
const vapidKey = normalizeVapidKey(import.meta.env.VITE_FIREBASE_VAPID_KEY);
if (!config || !vapidKey) {
return;
}
@@ -33,10 +33,21 @@ export async function ensureWebPushRegistration(): Promise<void> {
const registration = await navigator.serviceWorker.ready;
const app = getApps()[0] ?? initializeApp(config);
const messaging = getMessaging(app);
const token = await getToken(messaging, {
vapidKey,
serviceWorkerRegistration: registration,
});
let token: string | null = null;
try {
token = await getToken(messaging, {
vapidKey,
serviceWorkerRegistration: registration,
});
} catch (error) {
if (error instanceof DOMException && error.name === "InvalidAccessError") {
console.error(
"[web-push] Invalid VAPID key format. Check VITE_FIREBASE_VAPID_KEY in web env.",
);
return;
}
throw error;
}
if (!token) {
return;
}
@@ -107,3 +118,34 @@ function getFirebaseConfig():
appId,
};
}
function normalizeVapidKey(raw: string | undefined): string | null {
if (!raw) {
return null;
}
let key = raw.trim();
if (!key) {
return null;
}
// Accept accidental JSON payloads copied from docs/panels.
if (key.startsWith("{") && key.endsWith("}")) {
try {
const parsed = JSON.parse(key) as { vapidKey?: string; publicKey?: string; key?: string };
key = (parsed.vapidKey ?? parsed.publicKey ?? parsed.key ?? "").trim();
} catch {
return null;
}
}
// Strip wrapping quotes and whitespace/newlines.
key = key.replace(/^['"]|['"]$/g, "").replace(/\s+/g, "");
// Convert classic base64 chars to URL-safe format expected by PushManager/Firebase.
key = key.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
if (!/^[A-Za-z0-9\-_]+$/.test(key)) {
return null;
}
return key.length >= 80 ? key : null;
}