URS-001 · Secure Login with Unique User Credentials
Title: Secure Login with Unique User Credentials Date: 2026-04-23T03:33:41.949Z Duration: 91.9s Overall Status: ✅ PASS
User Requirement
Section titled “User Requirement”The system shall provide secure login using unique user credentials.
Source: User_Requirement_Specifications_ZuriMED_DeviceFlow.xlsx — the run below proves the system meets this requirement.
Environment
Section titled “Environment”- Inbox URL: http://localhost:61662
- Database: localhost:61663/cc_repinbox_dev
Status: ✅ PASS
Test Steps
Section titled “Test Steps”Each step below corresponds to one Playwright test that ran sequentially. Screenshots and video recordings provide visual evidence of the UI behaviour.
1. Step 1: Login page loads correctly — ✅ PASS
Section titled “1. Step 1: Login page loads correctly — ✅ PASS”What this step proves:
The system presents a login form with email and password fields and a password reset link. This confirms the authentication entry point is functional and that all users are directed to credential-based login rather than any unauthenticated route.
Screenshots:

Video recording:
2. Step 2: Valid login - Distributor user — ✅ PASS
Section titled “2. Step 2: Valid login - Distributor user — ✅ PASS”What this step proves:
A distributor user authenticates successfully with correct credentials. The system validates the credentials, creates a session, and redirects the user to the authenticated application. This demonstrates that valid credentials grant access as required by URS-001.
Audit events generated by this step:
(Evidence matched by declared name — step timing not available or no events fell in window)
| Time | Type | Action | User | Org | Performed |
|---|---|---|---|---|---|
| 2026-04-23 03:33:52Z | user_log | user:login | dan.distributor@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:33:59Z | user_log | user:login | mark.manufacturer@zurimed.com | ZuriMED | — |
| 2026-04-23 03:34:06Z | user_log | user:login | alex.admin@zurimed.com | ZuriMED | — |
| 2026-04-23 03:34:50Z | user_log | user:login | alex.admin@zurimed.com | ZuriMED | — |
| 2026-04-23 03:34:57Z | user_log | user:login | dan.distributor@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:34:58Z | user_log | user:login | alex.admin@zurimed.com | ZuriMED | — |
| 2026-04-23 03:35:06Z | user_log | user:login | alex.admin@zurimed.com | ZuriMED | — |
Screenshots:

Video recording:
3. Step 3: Valid login - Manufacturer user — ✅ PASS
Section titled “3. Step 3: Valid login - Manufacturer user — ✅ PASS”What this step proves:
A manufacturer-type user authenticates successfully, confirming that the secure credential flow handles multiple organization types uniformly. No special path exists for different org types.
Audit events generated by this step:
(Evidence matched by declared name — step timing not available or no events fell in window)
| Time | Type | Action | User | Org | Performed |
|---|---|---|---|---|---|
| 2026-04-23 03:33:52Z | user_log | user:login | dan.distributor@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:33:59Z | user_log | user:login | mark.manufacturer@zurimed.com | ZuriMED | — |
| 2026-04-23 03:34:06Z | user_log | user:login | alex.admin@zurimed.com | ZuriMED | — |
| 2026-04-23 03:34:50Z | user_log | user:login | alex.admin@zurimed.com | ZuriMED | — |
| 2026-04-23 03:34:57Z | user_log | user:login | dan.distributor@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:34:58Z | user_log | user:login | alex.admin@zurimed.com | ZuriMED | — |
| 2026-04-23 03:35:06Z | user_log | user:login | alex.admin@zurimed.com | ZuriMED | — |
Screenshots:

Video recording:
4. Step 4: Valid login - Admin user — ✅ PASS
Section titled “4. Step 4: Valid login - Admin user — ✅ PASS”What this step proves:
An admin user authenticates successfully, confirming that all system roles use the same credential-based authentication mechanism.
Audit events generated by this step:
(Evidence matched by declared name — step timing not available or no events fell in window)
| Time | Type | Action | User | Org | Performed |
|---|---|---|---|---|---|
| 2026-04-23 03:33:52Z | user_log | user:login | dan.distributor@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:33:59Z | user_log | user:login | mark.manufacturer@zurimed.com | ZuriMED | — |
| 2026-04-23 03:34:06Z | user_log | user:login | alex.admin@zurimed.com | ZuriMED | — |
| 2026-04-23 03:34:50Z | user_log | user:login | alex.admin@zurimed.com | ZuriMED | — |
| 2026-04-23 03:34:57Z | user_log | user:login | dan.distributor@stellartech.com | StellarTech Medical Solutions | — |
| 2026-04-23 03:34:58Z | user_log | user:login | alex.admin@zurimed.com | ZuriMED | — |
| 2026-04-23 03:35:06Z | user_log | user:login | alex.admin@zurimed.com | ZuriMED | — |
Screenshots:

Video recording:
5. Step 5: Invalid credentials - Wrong password — ✅ PASS
Section titled “5. Step 5: Invalid credentials - Wrong password — ✅ PASS”What this step proves:
Attempting to log in with a valid registered email but an incorrect password is rejected. The system returns a generic error message and keeps the user on the login page. The exact error text is captured for comparison in Step 6 to verify protection against email enumeration.
Screenshots:

Video recording:
6. Step 6a: Invalid credentials - Non-existent email — ✅ PASS
Section titled “6. Step 6a: Invalid credentials - Non-existent email — ✅ PASS”What this step proves:
Attempting to log in with an email address that has never been registered returns the exact same error message as Step 5. Identical responses for wrong-password and unknown-email requests prevent attackers from determining whether a given email address exists in the system.
Screenshots:

Video recording:
7. Step 6b: Locked account - inactive user cannot login — ✅ PASS
Section titled “7. Step 6b: Locked account - inactive user cannot login — ✅ PASS”What this step proves:
A user whose organization membership has been deactivated is blocked from logging in even when submitting the correct credentials. This confirms that deactivating a user account takes effect immediately and that credential validity alone is insufficient for access.
Screenshots:

Video recording:
8. Step 7: Empty field validation — ✅ PASS
Section titled “8. Step 7: Empty field validation — ✅ PASS”What this step proves:
Submitting the login form with empty fields triggers validation errors before any server request is made, displaying field-level messages such as “Invalid email” and “Password is required”. This confirms that required-field enforcement provides clear feedback and prevents malformed requests.
Screenshots:


Video recording:
9. Step 8: Session security - Cookie verification — ✅ PASS
Section titled “9. Step 8: Session security - Cookie verification — ✅ PASS”What this step proves:
After successful login the session cookie attributes are inspected. The httpOnly flag confirms that JavaScript cannot read the token, mitigating XSS-based session theft. The SameSite=Lax setting blocks cross-site request forgery. Cookie evidence is written to session-cookie-evidence.json.
Screenshots:

Video recording:
10. Step 9: Session isolation - Multiple users — ✅ PASS
Section titled “10. Step 9: Session isolation - Multiple users — ✅ PASS”What this step proves:
Two users log in simultaneously in separate browser contexts (equivalent to separate incognito windows) and each receives a distinct, non-overlapping session token. This confirms that sessions are fully isolated and one user’s session cannot be used to access another user’s account.
Screenshots:


Video recording:
11. Step 10: Logout and session termination — ✅ PASS
Section titled “11. Step 10: Logout and session termination — ✅ PASS”What this step proves:
A logged-in user opens the sidebar user menu and clicks Logout. The server invalidates the session, clears the session cookie, and redirects the browser. A subsequent attempt to access /inbox confirms that the session can no longer authenticate: the user is redirected to login.
Screenshots:



Video recording:
Database Validations
Section titled “Database Validations”The following SQL queries ran against the application database after the Playwright scenarios completed. Each query asserts a specific condition that proves the feature under test persisted its data correctly.
Demo users exist — ✅ PASS
Section titled “Demo users exist — ✅ PASS”Assertion: All 4 demo users should exist in the users table
SELECT id, email, name, created_at FROM users WHERE email IN ( 'alex.admin@zurimed.com', 'mark.manufacturer@zurimed.com', 'dan.distributor@stellartech.com', 'demo.user@zurimed.com' ) ORDER BY email| id | name | created_at | |
|---|---|---|---|
| f6a7b8c9-d0e1-2345-f123-456789012345 | alex.admin@zurimed.com | Alex Admin | 2026-04-23T02:44:53.474Z |
| c3d4e5f6-a7b8-9012-cdef-123456789012 | dan.distributor@stellartech.com | Dan Distributor | 2026-04-23T02:44:53.474Z |
| e5f6a7b8-c9d0-1234-ef12-345678901234 | demo.user@zurimed.com | Demo User | 2026-04-23T02:44:53.474Z |
| d4e5f6a7-b8c9-0123-def1-234567890123 | mark.manufacturer@zurimed.com | Mark Manufacturer | 2026-04-23T02:44:53.474Z |
No duplicate emails — ✅ PASS
Section titled “No duplicate emails — ✅ PASS”Assertion: No email address should appear more than once in the users table
SELECT email, COUNT(*) as count FROM users GROUP BY email HAVING COUNT(*) > 1No rows returned
Passwords are hashed — ✅ PASS
Section titled “Passwords are hashed — ✅ PASS”Assertion: All password hashes should use Argon2id algorithm (not plaintext)
SELECT id, email, LEFT(password_hash, 10) as hash_prefix, password_hash LIKE '$argon2id$%' as is_argon2 FROM users WHERE email IN ( 'alex.admin@zurimed.com', 'mark.manufacturer@zurimed.com', 'dan.distributor@stellartech.com', 'demo.user@zurimed.com' ) ORDER BY email| id | hash_prefix | is_argon2 | |
|---|---|---|---|
| f6a7b8c9-d0e1-2345-f123-456789012345 | alex.admin@zurimed.com | $argon2id$ | true |
| c3d4e5f6-a7b8-9012-cdef-123456789012 | dan.distributor@stellartech.com | $argon2id$ | true |
| e5f6a7b8-c9d0-1234-ef12-345678901234 | demo.user@zurimed.com | $argon2id$ | true |
| d4e5f6a7-b8c9-0123-def1-234567890123 | mark.manufacturer@zurimed.com | $argon2id$ | true |
Recent sessions created — ✅ PASS
Section titled “Recent sessions created — ✅ PASS”Assertion: Sessions should have been created within the last 10 minutes for users who logged in during the test
SELECT s.id as session_id, u.email, s.created_at, s.expires_at FROM session s JOIN users u ON s.user_id = u.id WHERE u.email IN ( 'alex.admin@zurimed.com', 'mark.manufacturer@zurimed.com', 'dan.distributor@stellartech.com' ) AND s.created_at > NOW() - INTERVAL '10 minutes' ORDER BY s.created_at DESC LIMIT 10| session_id | created_at | expires_at | |
|---|---|---|---|
| 370952fde4ea3c8c4e87d89019e8baf9ee1c4ec8a8b5937ca38430f7d282b696 | alex.admin@zurimed.com | 2026-04-23T03:34:58.960Z | 2026-05-23T03:34:58.956Z |
| d786cad8127a4714bdc7f9f78b063cf67e9f35584de478c03bb216aa014cd303 | dan.distributor@stellartech.com | 2026-04-23T03:34:57.649Z | 2026-05-23T03:34:57.646Z |
| 3e39cf0b2d2aa390637548cbd09f73afb0d4cda3aa848478de746260c55b4a38 | alex.admin@zurimed.com | 2026-04-23T03:34:50.181Z | 2026-05-23T03:34:50.178Z |
| 8b27bbd681daa18e9ccb495e372a745e8badcc85fc054b84d5d5eab4910a1314 | alex.admin@zurimed.com | 2026-04-23T03:34:06.729Z | 2026-05-23T03:34:06.727Z |
| cfc932e46aa3480b74f988caa91e97e1133c39dedf01f66b480d6fc7fb39ecdc | mark.manufacturer@zurimed.com | 2026-04-23T03:33:59.805Z | 2026-05-23T03:33:59.796Z |
| 97b8f110272dbe9989e4d4498df2a3ecb034a28280537462397d30d465c3ac2e | dan.distributor@stellartech.com | 2026-04-23T03:33:52.655Z | 2026-05-23T03:33:52.646Z |
Locked user is inactive — ✅ PASS
Section titled “Locked user is inactive — ✅ PASS”Assertion: demo.user@zurimed.com should have inactive org membership (locked account)
SELECT u.email, om.active, om.organization_id FROM organization_members om JOIN users u ON om.user_id = u.id WHERE u.email = 'demo.user@zurimed.com'| active | organization_id | |
|---|---|---|
| demo.user@zurimed.com | false | a1b2c3d4-e5f6-7890-abcd-ef1234567890 |
| demo.user@zurimed.com | false | b2c3d4e5-f6a7-8901-bcde-f12345678901 |
| demo.user@zurimed.com | false | 6763fc17-7da1-47e3-851e-8f4fac570dc6 |
Global email uniqueness — ✅ PASS
Section titled “Global email uniqueness — ✅ PASS”Assertion: Every user should have a unique email address
SELECT COUNT(DISTINCT email) as unique_emails, COUNT(*) as total_users FROM users WHERE email IS NOT NULL| unique_emails | total_users |
|---|---|
| 12 | 12 |
Audit & Email Assertion Ledger
Section titled “Audit & Email Assertion Ledger”Per-declaration outcome of every expectedAuditActions and expectedEmailTemplates entry written into the orchestrator. Missing evidence here is a real test failure, not a soft warning.
Audit Action Assertions
Section titled “Audit Action Assertions”Each row asserts that a declared expectedAuditActions entry produced a matching row in audit_events. A ❌ flips overall status to FAIL — the declaration is real proof, not just an annotation.
| Step | Expected Audit Action | Found |
|---|---|---|
| Step 2: Valid login - Distributor user | user_log:user:login | ✅ |
| Step 3: Valid login - Manufacturer user | user_log:user:login | ✅ |
| Step 4: Valid login - Admin user | user_log:user:login | ✅ |
Audit Log Events
Section titled “Audit Log Events”Every row written to audit_events while this test was running (scoped to the demo organizations). Provides compliance evidence that user actions are traced end-to-end (URS-003).
Capture window start: 2026-04-23T03:33:40.054Z
SELECT ae.created_at, ae.event_type, ae.action, ae.user_id, u.email AS user_email, ae.organization_id, o.name AS organization_name, ae.object_id, ae.secondary_object_id, ae.payload, ae.route, ae.trace_id FROM audit_events ae LEFT JOIN users u ON u.id = ae.user_id LEFT JOIN organizations o ON o.id = ae.organization_id WHERE ae.created_at >= $1 AND ae.organization_id = ANY($2::uuid[]) ORDER BY ae.created_at ASC8 event(s) captured:
| Time | Type | Action | User | Org | Object ID | Performed | Reason |
|---|---|---|---|---|---|---|---|
| 2026-04-23 03:33:52Z | user_log | user:login | dan.distributor@stellartech.com | StellarTech Medical Solutions | — | — | |
| 2026-04-23 03:33:59Z | user_log | user:login | mark.manufacturer@zurimed.com | ZuriMED | — | — | |
| 2026-04-23 03:34:06Z | user_log | user:login | alex.admin@zurimed.com | ZuriMED | — | — | |
| 2026-04-23 03:34:33Z | user_log | user:login_deactivated | demo.user@zurimed.com | ZuriMED | — | — | |
| 2026-04-23 03:34:50Z | user_log | user:login | alex.admin@zurimed.com | ZuriMED | — | — | |
| 2026-04-23 03:34:57Z | user_log | user:login | dan.distributor@stellartech.com | StellarTech Medical Solutions | — | — | |
| 2026-04-23 03:34:58Z | user_log | user:login | alex.admin@zurimed.com | ZuriMED | — | — | |
| 2026-04-23 03:35:06Z | user_log | user:login | alex.admin@zurimed.com | ZuriMED | — | — |
Downloads
Section titled “Downloads”- audit-events.json
- report.md
- result.json
- screenshots-index.json
- session-cookie-evidence.json
- step-timings.json