You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@texera.apache.org by gi...@apache.org on 2026/06/03 07:31:06 UTC
(texera) branch gh-readonly-queue/main/pr-5311-23c5fd2c13936e43c5094c041650c7c041fe9b22 created (now f7652bc510)
This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a change to branch gh-readonly-queue/main/pr-5311-23c5fd2c13936e43c5094c041650c7c041fe9b22
in repository https://gitbox.apache.org/repos/asf/texera.git
at f7652bc510 fix(frontend): stop forum login from looping when Flarum auth fails (#5311)
This branch includes the following new commits:
new f7652bc510 fix(frontend): stop forum login from looping when Flarum auth fails (#5311)
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(texera) 01/01: fix(frontend): stop forum login from looping when Flarum auth fails (#5311)
Posted by gi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/main/pr-5311-23c5fd2c13936e43c5094c041650c7c041fe9b22
in repository https://gitbox.apache.org/repos/asf/texera.git
commit f7652bc510bc4654c50a4df67735cbae47714407
Author: Matthew B. <mg...@uci.edu>
AuthorDate: Wed Jun 3 00:19:44 2026 -0700
fix(frontend): stop forum login from looping when Flarum auth fails (#5311)
### What changes were proposed in this PR?
- Add an `attemptRegister` flag to `DashboardComponent.forumLogin` so a
Flarum registration is attempted at most once, breaking the infinite
`auth -> register -> auth` cycle that occurred when `auth()` kept
failing with a non-404/500 status.
- After registering, the recursive call now passes `forumLogin(false)`;
if auth still fails on that pass it falls through to `displayForum =
false` instead of looping.
- Add an error handler to the `register()` subscription so a failed
registration hides the forum rather than being silently dropped.
### Any related issues, documentation, or discussions?
Closes: #5310
### How was this PR tested?
- Ran `yarn format:fix` (clean, no files changed).
- Manually traced the control flow: auth fail (non-404/500) now does
auth, register, auth, then stop, instead of recursing without bound.
### Was this PR authored or co-authored using generative AI tooling?
Co-authored with Claude Opus 4.8 in compliance with ASF
---------
Signed-off-by: Matthew B. <mg...@uci.edu>
---
.../component/dashboard.component.spec.ts | 67 +++++++++++++++++++++-
.../app/dashboard/component/dashboard.component.ts | 12 +++-
2 files changed, 75 insertions(+), 4 deletions(-)
diff --git a/frontend/src/app/dashboard/component/dashboard.component.spec.ts b/frontend/src/app/dashboard/component/dashboard.component.spec.ts
index 29ed8426fe..a53244b3cd 100644
--- a/frontend/src/app/dashboard/component/dashboard.component.spec.ts
+++ b/frontend/src/app/dashboard/component/dashboard.component.spec.ts
@@ -21,7 +21,7 @@ import { ComponentFixture, TestBed } from "@angular/core/testing";
import { DashboardComponent } from "./dashboard.component";
import { ChangeDetectorRef, EventEmitter, NgZone } from "@angular/core";
import { By } from "@angular/platform-browser";
-import { EMPTY, of } from "rxjs";
+import { EMPTY, of, throwError } from "rxjs";
import { UserService } from "../../common/service/user/user.service";
import { FlarumService } from "../service/user/flarum/flarum.service";
@@ -178,6 +178,71 @@ describe("DashboardComponent", () => {
expect(fixture.debugElement.query(By.css("#powered-by"))).toBeTruthy();
});
+ describe("forumLogin", () => {
+ const clearForumCookie = () =>
+ (document.cookie = "flarum_remember=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/");
+
+ beforeEach(() => {
+ clearForumCookie();
+ (userServiceMock.isLogin as Mock).mockReturnValue(true);
+ component.isLogin = true;
+ component.displayForum = true;
+ (flarumServiceMock.auth as Mock).mockClear();
+ (flarumServiceMock.register as Mock).mockClear();
+ });
+
+ afterEach(() => clearForumCookie());
+
+ it("stores the flarum_remember cookie on successful auth and does not register", () => {
+ (flarumServiceMock.auth as Mock).mockReturnValue(of({ token: "tok123" }));
+
+ component.forumLogin();
+
+ expect(document.cookie).toContain("flarum_remember=tok123");
+ expect(flarumServiceMock.register).not.toHaveBeenCalled();
+ });
+
+ it("hides the forum and does not register when auth fails with 404/500", () => {
+ (flarumServiceMock.auth as Mock).mockReturnValue(throwError(() => ({ status: 404 })));
+
+ component.forumLogin();
+
+ expect(component.displayForum).toBe(false);
+ expect(flarumServiceMock.register).not.toHaveBeenCalled();
+ });
+
+ it("registers at most once and stops when auth keeps failing (no infinite loop)", () => {
+ (flarumServiceMock.auth as Mock).mockReturnValue(throwError(() => ({ status: 401 })));
+ (flarumServiceMock.register as Mock).mockReturnValue(of(null));
+
+ component.forumLogin();
+
+ // auth -> register -> auth -> stop: register fires once, auth twice, then it terminates.
+ expect(flarumServiceMock.register).toHaveBeenCalledTimes(1);
+ expect(flarumServiceMock.auth).toHaveBeenCalledTimes(2);
+ expect(component.displayForum).toBe(false);
+ });
+
+ it("hides the forum when registration fails", () => {
+ (flarumServiceMock.auth as Mock).mockReturnValue(throwError(() => ({ status: 401 })));
+ (flarumServiceMock.register as Mock).mockReturnValue(throwError(() => ({ status: 500 })));
+
+ component.forumLogin();
+
+ expect(flarumServiceMock.register).toHaveBeenCalledTimes(1);
+ expect(component.displayForum).toBe(false);
+ });
+
+ it("does nothing when a flarum_remember cookie is already present", () => {
+ document.cookie = "flarum_remember=existing;path=/";
+
+ component.forumLogin();
+
+ expect(flarumServiceMock.auth).not.toHaveBeenCalled();
+ expect(flarumServiceMock.register).not.toHaveBeenCalled();
+ });
+ });
+
it("should hide the navbar on workflow workspace routes", () => {
expect(component.isNavbarEnabled("/user/workflow/42")).toBe(false);
expect(component.isNavbarEnabled("/user/workflow")).toBe(true);
diff --git a/frontend/src/app/dashboard/component/dashboard.component.ts b/frontend/src/app/dashboard/component/dashboard.component.ts
index aadf07d54b..8f8ba03b08 100644
--- a/frontend/src/app/dashboard/component/dashboard.component.ts
+++ b/frontend/src/app/dashboard/component/dashboard.component.ts
@@ -204,7 +204,7 @@ export class DashboardComponent implements OnInit {
});
}
- forumLogin() {
+ forumLogin(attemptRegister: boolean = true) {
if (!document.cookie.includes("flarum_remember") && this.isLogin) {
this.flarumService
.auth()
@@ -214,13 +214,19 @@ export class DashboardComponent implements OnInit {
document.cookie = `flarum_remember=${response.token};path=/`;
},
error: (err: unknown) => {
- if ([404, 500].includes((err as HttpErrorResponse).status)) {
+ // Stop retrying on a missing/broken forum service, or once we have
+ // already attempted a registration, to avoid an infinite
+ // auth -> register -> auth loop when auth keeps failing.
+ if ([404, 500].includes((err as HttpErrorResponse).status) || !attemptRegister) {
this.displayForum = false;
} else {
this.flarumService
.register()
.pipe(untilDestroyed(this))
- .subscribe(() => this.forumLogin());
+ .subscribe({
+ next: () => this.forumLogin(false),
+ error: () => (this.displayForum = false),
+ });
}
},
});