Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .freebuff/desktop-v2.db
Binary file not shown.
Binary file added .freebuff/desktop-v2.db-shm
Binary file not shown.
Binary file added .freebuff/desktop-v2.db-wal
Binary file not shown.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@ output/**/*.*

.env
.history/

# Local JWT secret used only for development
bbbeasy-backend/tmp/jwt.secret
18 changes: 2 additions & 16 deletions bbbeasy-backend/app/src/Core/Session.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ public function exists($key): bool
public function set($key, $value): void
{
$this->runtimeValues[$key] = $value;
$this->f3->set('SESSION.' . $key, $value);
}

/**
Expand Down Expand Up @@ -278,20 +277,7 @@ private function serializeUser(User $user): array

private function syncSessionState(): void
{
if (!$this->currentUser instanceof User) {
return;
}

$user = $this->serializeUser($this->currentUser);
$user['loggedIn'] = true;

$this->f3->set('SESSION.user', $user);
$this->f3->set('SESSION.user.loggedIn', true);
$this->f3->set('SESSION.user.id', $user['id']);
$this->f3->set('SESSION.user.role', $user['role']);
$this->f3->set('SESSION.user.roleId', $this->currentUser->role->id);
$this->f3->set('SESSION.user.username', $user['username']);
$this->f3->set('SESSION.user.email', $user['email']);
// JWT-only mode keeps the authenticated user in request memory only.
}

/**
Expand Down Expand Up @@ -386,7 +372,7 @@ private function isRevoked(string $jti): bool
return true;
}

return null !== \Cache::instance()->get($this->revokedTokenCacheKey($jti));
return false !== \Cache::instance()->get($this->revokedTokenCacheKey($jti));
}

private function revokedTokenCacheKey(string $jti): string
Expand Down
4 changes: 2 additions & 2 deletions bbbeasy-backend/tests/src/Actions/Account/LoginTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ public function testAuthenticateExistingUser($f3)
$test->expect(isset($payload['sub']) && (int) $payload['sub'] === (int) $user->id, 'JWT subject matches the authenticated user');
$test->expect(isset($payload['exp']) && \is_string($expiresAt) && strtotime($expiresAt) > $now, 'JWT expiry is set in the future');
$test->expect(isset($responseBody['session']['expiresAt']) && $responseBody['session']['expiresAt'] === $expiresAt, 'Login returns a concrete token expiration date');
$test->expect($f3->exists('SESSION.user'), 'Sessions is aware that the user us logged in');
$test->expect(null !== \Registry::get('session')->get('user'), 'JWT session keeps the authenticated user in memory');

UserFaker::logout();

Expand All @@ -179,7 +179,7 @@ public function testValidAuthentication($f3)
$user = UserFaker::create(UserRole::ADMINISTRATOR);
$data = ['email' => $user->email, 'password' => UserRole::ADMINISTRATOR . UserRole::ADMINISTRATOR];
$f3->mock(self::LOGIN_ROUTE, null, null, $this->postJsonData($data));
$test->expect($f3->exists('SESSION.user'), 'User with id "' . $user->id . '" is now logged in');
$test->expect(null !== \Registry::get('session')->get('user'), 'User with id "' . $user->id . '" is now logged in');

return $test->results();
}
Expand Down
4 changes: 3 additions & 1 deletion bbbeasy-backend/tests/src/Actions/Rooms/StartTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use Fake\PresetFaker;
use Fake\RoomFaker;
use Models\User;
use Registry;
use Test\Scenario;

/**
Expand Down Expand Up @@ -66,7 +67,8 @@ public function testValidRoom($f3)
$test = $this->newTest();

$loggedUser = new User();
$loggedUser->load(['id = ?', [$f3->get('SESSION.user.id')]]);
$currentUser = Registry::get('session')->get('user');

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

2. Null session user indexing 🐞 Bug ☼ Reliability

StartTest/ViewTest now index into $currentUser['id'] without verifying the session returned an
array, which can trigger warnings/failures when no user is loaded into the session.
Session::get('user') explicitly returns null when currentUser is not set.
Agent Prompt
## Issue description
Room tests assume `Registry::get('session')->get('user')` is always a non-null array and immediately access `$currentUser['id']`. When no authenticated user is present, this becomes an unsafe array-offset access.

## Issue Context
`Core\Session::get('user')` returns `null` if there is no authenticated `currentUser`, so tests should either (a) ensure login happens in their own setup, or (b) assert/fail clearly when `currentUser` is missing.

## Fix Focus Areas
- bbbeasy-backend/tests/src/Actions/Rooms/StartTest.php[69-72]
- bbbeasy-backend/tests/src/Actions/Rooms/ViewTest.php[69-72]
- bbbeasy-backend/app/src/Core/Session.php[99-111]

## Implementation notes
- In each test, add an explicit login/setup step before reading session user.
- Or add a guard:
  - if `$currentUser === null` (or not array / missing `id`), fail the test with a clear message.
  - then proceed to load the user.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

$loggedUser->load(['id = ?', [$currentUser['id']]]);
$preset = PresetFaker::create($loggedUser);
$room = RoomFaker::create($loggedUser, $preset);
$f3->mock(self::START_ROOM_ROUTE . $room->id, null, null);
Expand Down
4 changes: 3 additions & 1 deletion bbbeasy-backend/tests/src/Actions/Rooms/ViewTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
use Fake\PresetFaker;
use Fake\RoomFaker;
use Models\User;
use Registry;
use Test\Scenario;

/**
Expand Down Expand Up @@ -66,7 +67,8 @@ public function testValidLink($f3)
$test = $this->newTest();

$loggedUser = new User();
$loggedUser->load(['id = ?', [$f3->get('SESSION.user.id')]]);
$currentUser = Registry::get('session')->get('user');
$loggedUser->load(['id = ?', [$currentUser['id']]]);
$preset = PresetFaker::create($loggedUser);
$room = RoomFaker::create($loggedUser, $preset, 'abcdef-123456');
$f3->mock(self::VIEW_ROOM_ROUTE . $room->short_link, null, null);
Expand Down
2 changes: 1 addition & 1 deletion bbbeasy-frontend/.yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ approvedGitRepositories:

enableScripts: true

nodeLinker: node-modules
nodeLinker: pnp

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

3. Yarn runtime path not tracked 🐞 Bug ☼ Reliability

Frontend config switches to nodeLinker: pnp while yarnPath points to
.yarn/releases/yarn-4.16.0.cjs, but .gitignore ignores .yarn/*, so fresh clones/CI can fail to
run Yarn unless that runtime is provisioned out-of-band. This PR increases the likelihood of
install/build failures by changing the linker mode without ensuring the configured Yarn runtime path
is available.
Agent Prompt
## Issue description
The repo configures Yarn via `yarnPath: .yarn/releases/yarn-4.16.0.cjs` and now switches to `nodeLinker: pnp`. However, `.gitignore` ignores `.yarn/*`, which prevents the configured Yarn runtime from being committed by default; if the runtime isn’t present, Yarn execution/install can fail on clean environments.

## Issue Context
- Yarn Berry expects the `yarnPath` target to exist when Yarn starts.
- Ignoring `.yarn/*` means the critical `releases/` file is easy to omit from the repo.

## Fix Focus Areas
- bbbeasy-frontend/.yarnrc.yml[6-10]
- bbbeasy-frontend/.gitignore[30-31]

## Implementation notes
Choose one:
1) Commit the Yarn release file and narrow the ignore rules (e.g., ignore caches but keep `.yarn/releases/**`).
2) Remove `yarnPath` and rely on Corepack-managed Yarn, documenting the required version.
3) If CI provisions Yarn runtime separately, document that requirement explicitly and ensure pipelines install/copy the runtime before running `yarn`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


npmMinimalAgeGate: 0

Expand Down
3 changes: 3 additions & 0 deletions bbbeasy-frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
<link rel="manifest" href="/manifest.json" />
<link rel="icon" href="/images/favicon.png" />
<link rel="stylesheet" href="/icons/style.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Sora:wght@400;600;700;800&family=Inter:wght@400;500;600&family=JetBrains+Mono:wght@500&display=swap" rel="stylesheet">
<title>BBBEasy</title>
</head>
<body>
Expand Down
96 changes: 89 additions & 7 deletions bbbeasy-frontend/src/App-installer.css
Original file line number Diff line number Diff line change
Expand Up @@ -286,17 +286,19 @@
}
.site-header {
z-index: 1;
background: var(--bbbeasy-bg-layout) !important;
background: linear-gradient(135deg, rgba(5, 12, 35, 0.98) 0%, rgba(7, 25, 44, 0.98) 45%, rgba(9, 31, 62, 0.98) 100%) !important;
border-bottom: 1px solid rgba(96, 165, 250, 0.12);
box-shadow: 0 10px 28px rgba(2, 6, 23, 0.22);
}
.site-header .lang-btn {
border-color: transparent;
box-shadow: none;
color: var(--bbbeasy-darken-gray);
color: #dbe9ff;
padding: 0;
}
.site-header .lang-btn:hover,
.site-header .lang-btn.ant-dropdown-open {
color: #fbbc0b !important;
color: #38bdf8 !important;
outline: unset !important;
}
.site-header-inner {
Expand All @@ -314,15 +316,65 @@
height: auto;
max-height: 64px;
max-width: 64px;
filter: drop-shadow(0 0 12px rgba(59, 130, 246, 0.28));
}
.site-header-inner button {
background: transparent !important;
color: var(--bbbeasy-darken-gray) !important;
color: #edf4ff !important;
transition: color 0.25s ease, transform 0.25s ease, opacity 0.25s ease;
}
.site-header-inner button:hover,
.site-header-inner button:focus {
color: #38bdf8 !important;
transform: translateY(-1px);
}
.site-content {
margin: 25px 20px;
z-index: 2;
}
.site-sider {
background: #07192c !important;
}
.site-sider .logo {
background: #07192c !important;
}
.site-sider .menu-sider .site-menu {
color: #ffffff !important;
}
.site-sider .site-menu .ant-menu-item,
.site-sider .site-menu .ant-menu-submenu-title,
.site-sider .site-menu .ant-menu-title-content,
.site-sider .site-menu .ant-menu-item a,
.site-sider .site-menu .ant-menu-submenu-title a,
.site-sider .site-menu .anticon,
.site-sider .sider-new-btn {
color: #ffffff !important;
}
.site-sider .sider-new-btn {
background: #1677ff !important;
border-color: #1677ff !important;
}
.site-sider .sider-new-btn:hover,
.site-sider .sider-new-btn:focus {
background: #4096ff !important;
color: #ffffff !important;

Check warning on line 360 in bbbeasy-frontend/src/App-installer.css

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Text does not meet the minimal contrast requirement with its background.

See more on https://sonarcloud.io/project/issues?id=riadvice_hivelvet&issues=AZ_8yd7EfHkNYAeYYPUr&open=AZ_8yd7EfHkNYAeYYPUr&pullRequest=1072
border-color: #4096ff !important;
}
.site-sider .site-menu .ant-menu-submenu-title .ant-menu-title-content,
.site-sider .site-menu .ant-menu-item .ant-menu-title-content {
color: #ffffff !important;
}
.site-sider .site-menu .ant-menu-item-selected,
.site-sider .site-menu .ant-menu-submenu-selected > .ant-menu-submenu-title {
background: rgba(255, 255, 255, 0.08) !important;
}
.site-sider .site-menu .ant-menu-item:hover,
.site-sider .site-menu .ant-menu-submenu-title:hover,
.site-sider .site-menu .ant-menu-item:focus,
.site-sider .site-menu .ant-menu-submenu-title:focus {
background: rgba(255, 255, 255, 0.12) !important;
color: #ffffff !important;

Check warning on line 376 in bbbeasy-frontend/src/App-installer.css

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Text does not meet the minimal contrast requirement with its background.

See more on https://sonarcloud.io/project/issues?id=riadvice_hivelvet&issues=AZ_8yd7EfHkNYAeYYPUs&open=AZ_8yd7EfHkNYAeYYPUs&pullRequest=1072
}
.site-footer {
min-height: 50px;
z-index: 1;
Expand Down Expand Up @@ -367,11 +419,14 @@
}
/*********************************************/
.color-primary {
border-color: #fbbc0b !important;
background: #1677ff !important;
border-color: #1677ff !important;
color: #ffffff !important;

Check warning on line 424 in bbbeasy-frontend/src/App-installer.css

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Text does not meet the minimal contrast requirement with its background.

See more on https://sonarcloud.io/project/issues?id=riadvice_hivelvet&issues=AZ_8yd7EfHkNYAeYYPUt&open=AZ_8yd7EfHkNYAeYYPUt&pullRequest=1072
}
.color-primary:hover {
color: #ffcf33 !important;
border-color: #ffcf33 !important;
background: #4096ff !important;
border-color: #4096ff !important;
color: #ffffff !important;

Check warning on line 429 in bbbeasy-frontend/src/App-installer.css

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Text does not meet the minimal contrast requirement with its background.

See more on https://sonarcloud.io/project/issues?id=riadvice_hivelvet&issues=AZ_8yd7EfHkNYAeYYPUu&open=AZ_8yd7EfHkNYAeYYPUu&pullRequest=1072
}
.color-blue {
color: #fff !important;
Expand Down Expand Up @@ -443,6 +498,33 @@
.button-container .ant-form-item-control-input-content {
display: flex;
}
.modal-submit-btn .ant-btn-primary {
background: #1677ff !important;
border-color: #1677ff !important;
color: #ffffff !important;

Check warning on line 504 in bbbeasy-frontend/src/App-installer.css

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Text does not meet the minimal contrast requirement with its background.

See more on https://sonarcloud.io/project/issues?id=riadvice_hivelvet&issues=AZ_8yd7EfHkNYAeYYPUv&open=AZ_8yd7EfHkNYAeYYPUv&pullRequest=1072
}
.modal-submit-btn .ant-btn-primary:hover,
.modal-submit-btn .ant-btn-primary:focus {
background: #4096ff !important;
border-color: #4096ff !important;
color: #ffffff !important;
}

.ant-page-header .ant-btn-primary,
.site-page-header .ant-btn-primary {
background: #1677ff !important;
border-color: #1677ff !important;
color: #ffffff !important;
}

.ant-page-header .ant-btn-primary:hover,
.ant-page-header .ant-btn-primary:focus,
.site-page-header .ant-btn-primary:hover,
.site-page-header .ant-btn-primary:focus {
background: #4096ff !important;
border-color: #4096ff !important;
color: #ffffff !important;

Check warning on line 526 in bbbeasy-frontend/src/App-installer.css

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Text does not meet the minimal contrast requirement with its background.

See more on https://sonarcloud.io/project/issues?id=riadvice_hivelvet&issues=AZ_8yd7EfHkNYAeYYPUy&open=AZ_8yd7EfHkNYAeYYPUy&pullRequest=1072
}
.final-step-btn {
width: 81%;
display: block;
Expand Down
Loading