Authentication and Tenant UX - RodrigoMattosoSilveira/EnterpriseRemoteSystems GitHub Wiki
Bite 28D — Authentication and Tenant UX
Manual Promotion Test Plan
Issue branch: 680-bite-28d-authentication-and-tenant-ux
Purpose: Verify browser authentication, tenant selection, authorization-aware navigation, password workflows, account administration, and session handling before promotion.
1. Preconditions
From the project root, prepare the local database and start the application:
scripts/ers-b28c-prepare-test-data-final.sh
make local-backend
make local-frontend
Use a normal browser window for the primary test session and a private/incognito window for account and session-isolation tests.
Confirm:
- Backend health is available.
- Frontend opens successfully.
- The local preparation script completed without errors.
- The generated authentication credentials are available from the script output or:
source /tmp/ers-b28c-manual-env.sh
Do not start the frontend with:
ERS_LOCAL_AUTHZ_BOOTSTRAP=true
Normal Bite 28D testing must use authenticated browser sessions rather than bootstrap-header impersonation.
Required Manual Tests
2. Protected Route Redirect
- Sign out or clear all ERS cookies.
- Navigate directly to:
http://localhost:5173/people
Expected
- ✔︎ The browser redirects to
/login. - ✔︎ The URL includes a
returnTovalue for/people. - vThe People page is not briefly exposed before redirection.
- ✔︎ A login form is displayed.
Result: ✔︎ Pass ☐ Fail
3. Application Administrator Login
- On the login page, enter the prepared Application Administrator login and password.
- Submit the form.
Expected
- ✔︎ Login succeeds without actor headers.
- vThe browser returns to the originally requested page.
- ✔︎ The application shell is visible.
- ✔︎ The current user’s display name or login is shown.
- ✔︎ The selected tenant is shown.
- ✔︎ Application-administration navigation is visible.
Confirm access to:
- ✔︎ People
- ✔︎ Collaborators
- ✔︎ Expenses
- ✔︎ Receipts
- ✔︎ Work Periods
- ✔︎ Reference Data
- ✔︎ Authorization administration
- ✔︎ Authentication administration
- ✔︎ Tenant administration
- ✔︎ Gold Prices
- ✔︎ Settings, where applicable
Result: ✔︎ Pass ☐ Fail
4. Invalid Login
-
Sign out.
-
Attempt login using:
- a valid login with an incorrect password;
- an unknown login;
- empty login and password fields.
Expected
- ✔︎ Invalid credentials do not create a session.
- ✔︎ The user remains on the login page.
- ✔︎ A clear, non-technical error is displayed.
- ✔︎ The application does not reveal whether a particular account exists.
- ✔︎ Empty fields produce field-level or form-level validation.
- vNo protected navigation is displayed.
Result: ✔︎ Pass ☐ Fail
5. Current User and Tenant Display
- Log in as the Application Administrator.
- Inspect the top bar or application shell.
Expected
- ✔︎ The authenticated account is correctly identified.
- ✔︎ The current tenant is clearly shown.
- ✔︎ Refreshing the browser preserves the authenticated session.
- ✔︎ Refreshing does not return the user to the login page.
- ✔︎ Refreshing does not change the selected tenant unexpectedly.
Result: ✔︎ Pass ☐ Fail
6. Tenant Selection
This test requires at least two active tenants.
- Log in as the Application Administrator.
- Open the tenant selector.
- Confirm that active tenants appear.
- Select a tenant other than
default. - Navigate through at least two tenant-scoped pages.
- Refresh the browser.
- Return to the
defaulttenant.
Expected
- ✔︎ All active tenants are available to the Application Administrator.
- ✔︎ Inactive tenants are not selectable.
- ✔︎ Selecting a tenant updates the displayed current tenant.
- ✔︎ Tenant-scoped pages reload using the selected tenant.
- ✔︎ Data from the previously selected tenant is not left in the page.
- ✔︎ The selected tenant survives a browser refresh.
- ✔︎ Returning to
defaultrestores the default tenant’s data.
Verify at least one tenant-specific data difference, such as:
- ✔︎ People
- ✔︎ Collaborators
- ✔︎ Reference Data
- ✔︎ Expenses
- ✔︎ Work Periods
Result: v Pass ☐ Fail
7. Tenant-Scoped User Access
- ✔︎ Sign out.
- ✔︎ Log in using a prepared Tenant Administrator or tenant-scoped operator account.
- ✔︎ Inspect the tenant selector and navigation.
Expected
- ✔︎ Only tenants covered by the actor’s active grants are shown.
- ✔︎ The user cannot select an ungranted tenant.
- ✔︎ Application-wide administration links are hidden.
- ✔︎ Tenant-appropriate navigation remains visible.
- ✔︎ Direct navigation to an application-only administration route does not expose the page.
Test direct access to:
✔︎ /admin/authorization
✔︎ /admin/authentication
✔︎ /tenants
Expected for unauthorized routes
- ✔︎ Access is refused.
- ✔︎ The user sees the Forbidden page or another intentional access-denied experience.
- ✔︎ The application does not display protected data before denial.
Result: ✔︎ Pass ☐ Fail
8. Permission-Aware Navigation
8.1 Objective
Verify that each prepared account:
- Sees exactly the navigation links granted by its effective permissions.
- Can open every visible navigation link.
- Cannot access hidden routes by entering their URLs directly.
- Can select only tenants covered by its active role grants.
- Receives the controlled ERS Forbidden page for unauthorized direct access.
8.2 Preconditions
- The local backend and frontend are running.
- The Bite 28C/28D preparation script has completed successfully.
- The generated account environment file exists:
source /tmp/ers-b28c-manual-env.sh
- Display the prepared logins and assigned tenants:
printf 'Application Administrator: %s\n' "$ADMIN_LOGIN"
printf 'Tenant Administrator: %s\n' "$TENANT_ADMIN_LOGIN"
printf 'Earnings Operator: %s\n' "$EARNINGS_LOGIN"
printf 'Expenses Operator: %s\n' "$EXPENSES_LOGIN"
printf 'Primary tenant: %s\n' "$PRIMARY_TENANT_ID"
printf 'Secondary tenant: %s\n' "$SECOND_TENANT_ID"
Expected primary tenant:
default
The prepared Tenant Administrator, Earnings Operator, and Expenses Operator are assigned to the default tenant.
Use these variables for login:
| Role | Login | Password |
|---|---|---|
| Application Administrator | $ADMIN_LOGIN |
$ADMIN_PASSWORD |
| Tenant Administrator | $TENANT_ADMIN_LOGIN |
$TENANT_ADMIN_PASSWORD |
| Earnings Operator | $EARNINGS_LOGIN |
$EARNINGS_PASSWORD |
| Expenses Operator | $EXPENSES_LOGIN |
$EXPENSES_PASSWORD |
Before starting each role test:
- Click Sign out if another account is logged in.
- Confirm the browser displays
/login. - Log in with the account listed for that role.
- Keep the selected tenant as
defaultunless the test explicitly says otherwise.
8.3 Common Forbidden Result
Whenever a direct URL is unauthorized, the browser must navigate to:
/forbidden
The page must display:
Access forbidden
and:
Your current role does not permit this operation in the selected tenant.
The page must also display the link:
Return to ERS
The following outcomes are failures:
- ✔︎ The protected page opens.
- ✔︎ Protected data briefly appears before redirection.
- ✔︎ A raw JSON error is displayed.
- ✔︎ An unhandled exception or blank page appears.
- ✔︎ The user remains on the protected URL.
- vThe response is shown as Page not found instead of Access forbidden.
8.4 Application Administrator
Account
Login: $ADMIN_LOGIN
Password: $ADMIN_PASSWORD
Scope: APPLICATION
Tenant selector
After login:
- ✔︎ Open the tenant selector.
- ✔︎ Confirm
defaultis available. - ✔︎ Confirm every active tenant granted through the Application Administrator’s global scope is available.
- ✔︎ Confirm the selector is not restricted to only
default. - ✔︎ Select
defaultbefore continuing.
Expected navigation links
The following links must be displayed, in this order:
| Order | Link | URL | Expected page heading |
|---|---|---|---|
| 1 | People | /people |
People |
| 2 | Collaborators | /collaborators |
Collaborators |
| 3 | Expenses | /expenses |
Expenses |
| 4 | Work periods | /work-periods |
Work Periods |
| 5 | Gold production | /gold-production |
Gold Production |
| 6 | Outstanding receipts | /receipts/outstanding |
Outstanding receipts |
| 7 | Tenants | /admin/tenants |
Tenants |
| 8 | Authentication | /admin/authentication |
Authentication Accounts |
| 9 | Authorization | /admin/authorization |
Authorization |
| 10 | Audit logs | /admin/audit-logs |
Audit Log Viewer |
| 11 | Reference data | /admin/reference-data |
Reference Data |
| 12 | Gold prices | /admin/gold-prices |
Gold Prices |
| 13 | Price list | /admin/price-list-items |
Price List Items |
| 14 | Account settings | /admin/current-account-settings |
Current Account Settings |
| 15 | Change password | /password/change |
Change password |
Test procedure
-
Record the complete navigation list.
-
Compare it to the table above.
-
Click People.
-
Confirm the URL is
/people. -
Confirm the
Peopleheading is displayed. -
Repeat for every link in the table.
-
For each page, confirm:
- ✔︎ The expected heading is displayed.
- ✔︎ The Access forbidden page is not displayed.
- ✔︎ No authorization error panel is displayed.
- ✔︎ No HTTP
401or403message is visible.
-
Return to
/peopleafter completing the checks.
Direct unauthorized URL
Not applicable.
The Application Administrator has the wildcard permission * with application scope. There is no authenticated ERS administration route that this role is expected to be forbidden from accessing.
Do not substitute a nonexistent URL for this test; a 404 Page not found result does not validate authorization.
Expected result
- ✔︎ All 15 links are visible.
- ✔︎ Every visible link opens successfully.
- vApplication-only links are available.
- ✔︎ The tenant selector permits access to all active authorized tenants.
- vNo navigation link produces a Forbidden response.
8.5 Tenant Administrator
Account
Login: $TENANT_ADMIN_LOGIN
Password: $TENANT_ADMIN_PASSWORD
Scope: TENANT
Tenant: default
Tenant selector
After login:
- Open the tenant selector.
- Confirm
defaultis displayed. - Confirm no tenant without an active grant for this account is displayed.
- Specifically confirm that
B28A_MANUAL_20260719is absent unless this actor was separately grantedTENANT_ADMINfor that tenant. - Confirm the user cannot type or select an arbitrary tenant ID.
Expected navigation links
The following links must be displayed, in this order:
| Order | Link | URL | Expected page heading |
|---|---|---|---|
| 1 | People | /people |
People |
| 2 | Collaborators | /collaborators |
Collaborators |
| 3 | Expenses | /expenses |
Expenses |
| 4 | Work periods | /work-periods |
Work Periods |
| 5 | Gold production | /gold-production |
Gold Production |
| 6 | Outstanding receipts | /receipts/outstanding |
Outstanding receipts |
| 7 | Audit logs | /admin/audit-logs |
Audit Log Viewer |
| 8 | Reference data | /admin/reference-data |
Reference Data |
| 9 | Gold prices | /admin/gold-prices |
Gold Prices |
| 10 | Price list | /admin/price-list-items |
Price List Items |
| 11 | Account settings | /admin/current-account-settings |
Current Account Settings |
| 12 | Change password | /password/change |
Change password |
The following application-scoped links must not be displayed:
Tenants
Authentication
Authorization
The Authorization link is application-scoped. If it appears for the Tenant Administrator, record the test as failed even if clicking it later produces a Forbidden page.
Test procedure
- Record the complete navigation list.
- Confirm it contains exactly the 12 expected links.
- Confirm Tenants, Authentication, and Authorization are absent.
- Click each displayed link.
- Confirm the expected URL and heading from the table.
- Confirm no displayed link redirects to
/forbidden. - Confirm each page shows data only for
default. - Return to
/people.
Direct unauthorized URL
Enter this URL directly:
/admin/authentication
Expected direct-access result
- ✔︎ The browser navigates to
/forbidden. - ✔︎ The heading is
Access forbidden. - ✔︎ The standard Forbidden message is displayed.
- ✔︎ No authentication-account data is shown.
- ✔︎ Returning to ERS does not add the Authentication link to navigation.
Expected result
- ✔︎ Only tenant-authorized operational and administration links are visible.
- ✔︎ Application-level tenant, authentication, and authorization administration links are hidden.
- ✔︎ Every visible link opens successfully.
- ✔︎ Direct access to
/admin/authenticationis denied with the controlled Forbidden page.
8.6 Earnings Operator
Account
Login: $EARNINGS_LOGIN
Password: $EARNINGS_PASSWORD
Scope: TENANT
Tenant: default
Post-login landing behavior
After successful login, the user must be taken to an authorized page.
The preferred landing page for this role is:
/collaborators
The following is a failure:
Login succeeds → browser opens / or /people → browser redirects to /forbidden
If that failure occurs:
- Record it as a permission-aware landing-page defect.
- Manually enter
/collaborators. - Continue the remaining navigation checks.
Tenant selector
- Open the tenant selector.
- Confirm only
defaultis available. - Confirm
B28A_MANUAL_20260719and other ungranted tenants are absent.
Expected navigation links
Only these links must be displayed:
| Order | Link | URL | Expected page heading |
|---|---|---|---|
| 1 | Collaborators | /collaborators |
Collaborators |
| 2 | Work periods | /work-periods |
Work Periods |
| 3 | Gold production | /gold-production |
Gold Production |
| 4 | Change password | /password/change |
Change password |
The following links must not be displayed:
✔︎ People
✔︎ Expenses
✔︎ Outstanding receipts
✔︎ Tenants
✔︎ Authentication
✔︎ Authorization
✔︎ Audit logs
✔︎ Reference data
✔︎ Gold prices
✔︎ Price list
✔︎ Account settings
Test procedure
- Record the complete navigation list.
- Confirm it contains exactly the four expected links.
- Click Collaborators.
- Confirm
/collaboratorsopens with theCollaboratorsheading. - Click Work periods.
- Confirm
/work-periodsopens with theWork Periodsheading. - Click Gold production.
- Confirm
/gold-productionopens with theGold Productionheading. - Click Change password.
- Confirm
/password/changeopens with theChange passwordheading. - Confirm none of these links produces a Forbidden page or authorization error.
Direct unauthorized URL
Enter:
/expenses
Expected direct-access result
- ✔︎ The browser navigates to
/forbidden. - ✔︎ The heading is
Access forbidden. - vNo Expense list or Expense data is displayed.
- vReturning to ERS does not add Expenses to navigation.
Expected result
- ✔︎ Only Collaborators, Work periods, Gold production, and Change password are visible.
- vAll four visible links open successfully.
- ✔︎ Expense access is denied.
- The account cannot select another tenant. v
8.7 Expenses Operator
Account
Login: $EXPENSES_LOGIN
Password: $EXPENSES_PASSWORD
Scope: TENANT
Tenant: default
Post-login landing behavior
After successful login, the user must be taken to an authorized page.
The preferred landing page for this role is:
/collaborators
The following is a failure:
Login succeeds → browser opens / or /people → browser redirects to /forbidden
If that failure occurs:
- Record it as a permission-aware landing-page defect.
- Manually enter
/collaborators. - Continue the remaining navigation checks.
Tenant selector
- Open the tenant selector.
- Confirm only
defaultis available. - Confirm
B28A_MANUAL_20260719and other ungranted tenants are absent.
Expected navigation links
Only these links must be displayed:
| Order | Link | URL | Expected page heading |
|---|---|---|---|
| 1 | Collaborators | /collaborators |
Collaborators |
| 2 | Expenses | /expenses |
Expenses |
| 3 | Outstanding receipts | /receipts/outstanding |
Outstanding receipts |
| 4 | Gold prices | /admin/gold-prices |
Gold Prices |
| 5 | Price list | /admin/price-list-items |
Price List Items |
| 6 | Change password | /password/change |
Change password |
The following links must not be displayed:
✔︎ People
✔︎ Work periods
✔︎ Gold production
✔︎ Tenants
✔︎ Authentication
✔︎ Authorization
✔︎ Audit logs
✔︎ Reference data
✔︎ Account settings
Test procedure
- Record the complete navigation list.
- Confirm it contains exactly the six expected links.
- Click Collaborators.
- Confirm
/collaboratorsopens with theCollaboratorsheading. - Click Expenses.
- Confirm
/expensesopens with theExpensesheading. - Click Outstanding receipts.
- Confirm
/receipts/outstandingopens with theOutstanding receiptsheading. - Click Gold prices.
- Confirm
/admin/gold-pricesopens with theGold Pricesheading. - Click Price list.
- Confirm
/admin/price-list-itemsopens with thePrice List Itemsheading. - Click Change password.
- Confirm
/password/changeopens with theChange passwordheading. - Confirm none of these links produces a Forbidden page or authorization error.
Direct unauthorized URL
Enter:
/work-periods
Expected direct-access result
- ✔︎ The browser navigates to
/forbidden. - ✔︎ The heading is
Access forbidden. - ✔︎ No Work Period list or planning data is displayed.
- ✔︎ Returning to ERS does not add Work periods to navigation.
Expected result
- ✔︎ Only Collaborators, Expenses, Outstanding receipts, Gold prices, Price list, and Change password are visible.
- ✔︎ Every visible link opens successfully.
- ✔︎ Work Period and Gold Production access is denied.
- ✔︎ The account cannot select another tenant.
8.8 Final Result Matrix
Record the result using this matrix:
| Role | Correct tenant choices | Exact navigation links | All visible links accessible | Direct URL denied | Result |
|---|---|---|---|---|---|
| Application Administrator | Pass / Fail | Pass / Fail | Pass / Fail | N/A | Pass / Fail |
| Tenant Administrator | Pass / Fail | Pass / Fail | Pass / Fail | /admin/authentication |
Pass / Fail |
| Earnings Operator | Pass / Fail | Pass / Fail | Pass / Fail | /expenses |
Pass / Fail |
| Expenses Operator | Pass / Fail | Pass / Fail | Pass / Fail | /work-periods |
Pass / Fail |
The section passes only when:
- Every role sees exactly its expected navigation links.
- No visible link leads to a Forbidden page.
- Every hidden-route direct-access test leads to the controlled Forbidden page.
- Tenant-scoped accounts can select only tenants for which they have active grants.
- Earnings and Expenses Operators land on an authorized page immediately after login.
9. Authentication Administration Page
- Log in as the Application Administrator.
- Open:
/admin/authentication
Expected
- ✔︎ Existing authentication accounts are listed.
- ✔︎ Account login, actor association, active status, and password-change status are understandable.
- ✔︎ Only an Application Administrator can access this page.
- ✔︎ Errors are shown within the page rather than as an unhandled browser failure.
Result: ✔︎ Pass ☐ Fail
10. Create Authentication Account
Use an active authorization actor that does not yet have an authentication account.
-
Open Authentication administration.
-
Create an account with:
- a unique login;
- a temporary password of at least 12 characters;
- “must change password” enabled.
-
Submit the form.
Expected
- ✔︎ The account is created successfully.
- ✔︎ The selected authorization actor is correctly associated.
- ✔︎ The account appears in the account list.
- ✔︎ The normalized login is displayed.
- ✔︎ The temporary password is not displayed after submission.
- ✔︎ Duplicate logins are rejected with a clear error.
Result: ✔︎ Pass ☐ Fail
11. Mandatory First Password Change
- Open a private/incognito browser window.
- Log in using the temporary account created above.
Expected
- ✔︎ Login succeeds.
- ✔︎ The user is directed to the password-change page.
- ✔︎ The user cannot enter normal application routes before changing the password.
- ✔︎ Direct navigation to
/peopleor another protected page returns the user to password change.
Change the password using:
- the temporary password as current password;
- a valid new password;
- matching confirmation.
Expected
- ✔︎ Password change succeeds.
- ✔︎ The previous session is ended.
- ✔︎ The user is returned to login.
- ✔︎ Login with the temporary password fails.
- ✔︎ Login with the new password succeeds.
- ✔︎ The user can now access permitted application routes.
Result: ✔︎ Pass ☐ Fail
12. Normal Password Change
- Log in with an established account.
- Open:
/password/change
- ✔︎ Try an incorrect current password.
- ✔︎ Try a new password shorter than 12 characters.
- ✔︎ Try mismatched confirmation values.
- ✔︎ Complete a valid password change.
Expected
- ✔︎ Incorrect current password is rejected.
- ✔︎ Weak or short passwords are rejected.
- ✔︎ Mismatched confirmation is rejected.
- ✔︎ A successful change revokes the current session.
- ✔︎ The user is returned to login.
- ✔︎ The old password no longer works.
- ✔︎ The new password works.
Restore the account to a known password if it will be reused for later testing.
Result: ✔︎ Pass ☐ Fail
13. Administrator-Issued Password Reset
- Log in as the Application Administrator.
- Open Authentication administration.
- Issue a password-reset token for a non-administrator test account.
Expected
- ✔︎ A one-time token is displayed.
- ✔︎ Its expiration is displayed.
- ✔︎ A reset-page link is provided.
- ✔︎ The token is displayed only as part of the issuance result and is not exposed in the account list.
Copy the reset link and open it in a private/incognito browser window.
Expected
- ✔︎ The reset page opens.
- ✔︎ The token is populated from the URL.
- ✔︎ A valid new password can be entered.
- ✔︎ Successful reset returns the user to login.
- ✔︎ The new password works.
- ✔︎ Reusing the same token fails.
- ✔︎ The old password no longer works.
Result: ✔︎ Pass ☐ Fail
14. Invalid and Expired Reset Token Handling
On /password/reset, test:
- ✔︎ no token;
- ✔︎ a fabricated token;
- ✔︎ a previously consumed token.
Expected
- ✔︎ The application does not crash.
- ✔︎ A clear invalid or expired-token message is displayed.
- ✔︎ No password is changed.
- ✔︎ No session is created automatically.
Result: ✔︎ Pass ☐ Fail
15. Account Deactivation and Reactivation
Use a disposable non-administrator authentication account.
- ✔︎ Log in with the disposable account in a private window.
- ✔︎ In the primary Application Administrator window, deactivate that account.
- ✔︎ Refresh or navigate in the private window.
- ✔︎ Attempt a new login with the deactivated account.
- ✔︎ Reactivate the account.
- ✔︎ Attempt login again.
Expected
After deactivation:
- ✔︎ Existing sessions no longer provide access.
- ✔︎ New login attempts are rejected.
- ✔︎ Protected API or page access redirects to login or reports session invalidation.
After reactivation:
- ✔︎ Login succeeds using the current password.
- ✔︎ The actor’s authorization grants still determine accessible tenants and pages.
Result: ✔︎ Pass ☐ Fail
16. Self-Deactivation Protection
- ✔︎ Log in as the Application Administrator.
- ✔︎ Open Authentication administration.
- ✔︎ Locate the account currently in use.
- vAttempt to deactivate it.
Expected
- ✔︎ The UI prevents or rejects self-deactivation.
- ✔︎ The current administrator session remains usable.
- ✔︎ A clear explanation is displayed.
Result: ✔︎ Pass ☐ Fail
17. Logout
- ✔︎ Log in normally.
- ✔︎ Select Sign out.
- ✔︎ After redirection, use the browser Back button.
- ✔︎ Attempt to revisit a protected route.
Expected
- ✔︎ Logout revokes the server-side session.
- ✔︎ The browser returns to login.
- ✔︎ Protected application content is not restored by the Back button.
- ✔︎ Direct protected-route access redirects to login.
- ✔︎ [email protected] in again creates a new working session.
Result: ✔︎ Pass ☐ Fail
18. Session Expiration or Revocation
A practical local method is to log in with a disposable account and then deactivate it from a second administrator session.
- ✔︎ Keep a protected page open in the disposable account’s browser.
- ✔︎ Deactivate the account or otherwise revoke its session.
- ✔︎ Trigger a protected request by refreshing or navigating.
Expected
- ✔︎ HTTP
401is handled centrally. - ✔︎ The user is redirected to login.
- ✔︎ A session-expired or authentication-required message is displayed.
- ✔︎ The original protected page is not left visible as if the session were valid.
- ✔︎ Logging in again restores normal operation.
Result: ✔︎ Pass ☐ Fail
19. Forbidden Handling
- ✔︎ Log in as a role without
authz.manage. - ✔︎ Navigate directly to:
/admin/authentication
- ✔︎ Attempt at least one other unauthorized route or operation.
Expected
- ✔︎ The application displays the Forbidden experience.
- ✔︎ The user remains authenticated.
- ✔︎ The application does not incorrectly redirect to login for an authorization failure.
- ✔︎ The page explains that the selected role or tenant does not permit access.
- ✔︎ Navigation back to an allowed page works.
Result: ✔︎ Pass ☐ Fail
20. No-Tenant-Access Experience
Use a disposable account whose actor has no active tenant grant.
- Log in with that account.
Expected
- Login does not expose tenant data.
- The application displays the No Tenant Access experience.
- No arbitrary default tenant is assigned.
- Protected tenant pages cannot be reached directly.
- Sign out remains available and functional.
Result: ☐ Pass ☐ Fail
21. Inactive Tenant Handling
- As Application Administrator, select a non-default test tenant.
- In another administrator session or through the supported tenant-management workflow, deactivate that tenant.
- Refresh the first session.
Expected
- The inactive tenant is no longer offered in the selector.
- The application falls back to another active granted tenant.
- Cached data from the inactive tenant is cleared.
- The application does not become stuck on an inaccessible tenant.
Reactivate or remove the disposable tenant after testing.
Result: ☐ Pass ☐ Fail
22. Browser Refresh and Deep-Link Checks
While authenticated, directly open and refresh:
/people
/collaborators
/expenses
/receipts/outstanding
/admin/authentication
/password/change
Expected
- Permitted routes survive a full browser refresh.
- Session identity is restored from the server.
- Tenant selection is retained.
- Unauthorized routes remain forbidden.
- Public password-reset and login pages remain accessible without a session.
Result: ☐ Pass ☐ Fail
23. Browser Console and Network Review
During the manual tests, inspect the browser console and Network panel.
Expected
- No repeated
401or403request loops. - No unhandled promise rejections.
- No React render-loop warnings.
- No authentication password appears in URLs or logs.
- Session cookies are HTTP-only.
- Session cookies are sent only to appropriate ERS requests.
- Caller-supplied
X-Actor-IDorX-Actor-Permissionsheaders are not used for normal browser authentication. - Tenant-bound requests carry the currently selected tenant.
- Switching tenants does not issue requests using the prior tenant after the transition completes.
Result: ☐ Pass ☐ Fail
Regression Checks
24. Core Workflow Smoke Test
While logged in as Application Administrator, perform one short workflow in each major area:
- Open People and view a Person.
- Open Collaborators and view a Collaborator.
- Open Expenses.
- Open Current Account.
- Open Outstanding Receipts.
- Open Work Period planning.
- Open Reference Data.
- Open Authorization administration.
- Open Authentication administration.
- Open Tenant management.
- Open Gold Prices.
Expected
- Pages load without authentication loops.
- The current tenant remains consistent.
- Existing Bite 27 and Bite 28C authorization protections remain effective.
- Normal workflows do not require bootstrap actor headers.
Result: ☐ Pass ☐ Fail
Promotion Gate
Promote Bite 28D only when all of the following are true:
- Application Administrator login works.
- Invalid login is safely rejected.
- Logout revokes the session.
- Protected routes redirect to login.
- Original routes are restored after login.
- Current user and current tenant are correctly displayed.
- Tenant switching changes tenant-scoped data.
- Tenant selection survives refresh.
- Inactive and ungranted tenants are unavailable.
- Role-based navigation matches effective permissions.
- Direct unauthorized access produces Forbidden, not data exposure.
- Authentication accounts can be created and managed.
- Self-deactivation is prevented.
- Mandatory first password change works.
- Normal password change revokes previous sessions.
- Administrator-issued reset tokens work once only.
- Deactivated accounts cannot log in or retain sessions.
- No-tenant-access handling works.
- No browser-console authentication errors or request loops remain.
- Existing People, Collaborator, Expense, Receipt, Work Period, and administration pages still load under authenticated sessions.
-
make local-checkpasses on the exact branch intended for promotion.
Promotion decision
Manual tests completed by:
Date:
Branch SHA:
Browser:
Result: APPROVE / DO NOT PROMOTE
Blocking observations: