Skip analytics init on apps without persistent token store (#1336)

Owned admin apps are constructed with `tokenStore: null`, which caused
EventTracker/SessionRecorder flushes to throw from
_ensurePersistentTokenStore() after #1331 removed the silencing.

<!--

Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md

-->


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Improved analytics stability and privacy by restricting session
recording and event tracking to environments with required persistent
storage.
* **Tests**
* Adjusted a few end-to-end tests to skip when running against a local
emulator to reduce spurious failures.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
BilalG1 2026-04-14 09:43:37 -07:00 committed by GitHub
parent 7caff35ba3
commit 2af2a591b4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 7 additions and 5 deletions

View File

@ -3,8 +3,10 @@ import { describe } from "vitest";
import { it } from "../../../../../helpers";
import { Auth, backendContext, createMailbox, niceBackendFetch, waitForOutboxEmailWithStatus } from "../../../../backend-helpers";
const isLocalEmulator = process.env.NEXT_PUBLIC_STACK_IS_LOCAL_EMULATOR === "true";
describe("POST /api/v1/internal/feedback", () => {
it("should send feedback from an authenticated user", async ({ expect }) => {
it.runIf(!isLocalEmulator)("should send feedback from an authenticated user", async ({ expect }) => {
const senderEmail = backendContext.value.mailbox.emailAddress;
const signInResult = await Auth.Otp.signIn();
const recipientMailbox = createMailbox("team@stack-auth.com");
@ -44,7 +46,7 @@ describe("POST /api/v1/internal/feedback", () => {
expect(messages[0].body?.text).toContain("Authenticated feedback from the dashboard.");
});
it("should send feedback without authentication (dev tool)", async ({ expect }) => {
it.runIf(!isLocalEmulator)("should send feedback without authentication (dev tool)", async ({ expect }) => {
const recipientMailbox = createMailbox("team@stack-auth.com");
const senderEmail = `devtool-user-${randomUUID()}@example.com`;
const subject = `[Support] ${senderEmail}`;
@ -81,7 +83,7 @@ describe("POST /api/v1/internal/feedback", () => {
expect(messages[0].body?.text).toContain("Unauthenticated feedback from the dev tool.");
});
it("should send bug reports with correct label", async ({ expect }) => {
it.runIf(!isLocalEmulator)("should send bug reports with correct label", async ({ expect }) => {
const recipientMailbox = createMailbox("team@stack-auth.com");
const reporterEmail = `bug-${randomUUID()}@example.com`;
const subject = `[Bug Report] ${reporterEmail}`;

View File

@ -563,7 +563,7 @@ export class _StackClientAppImplIncomplete<HasTokenStore extends boolean, Projec
return anonUser._internalSession;
};
if (isBrowserLike() && this._analyticsOptions?.replays?.enabled === true) {
if (isBrowserLike() && this._hasPersistentTokenStore() && this._analyticsOptions?.replays?.enabled === true) {
this._sessionRecorder = new SessionRecorder({
projectId: this.projectId,
sendBatch: async (body, opts) => {
@ -573,7 +573,7 @@ export class _StackClientAppImplIncomplete<HasTokenStore extends boolean, Projec
this._sessionRecorder.start();
}
if (isBrowserLike()) {
if (isBrowserLike() && this._hasPersistentTokenStore()) {
this._eventTracker = new EventTracker({
projectId: this.projectId,
sendBatch: async (body, opts) => {