Skip to content
Merged
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
49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,55 @@ Security is a top priority in this admin panel:
- **Input Validation:** All user inputs are validated and sanitized
- **XSS Prevention:** Output escaping prevents cross-site scripting

## Case Study

### Problem

Small phone retailers typically manage inventory in spreadsheets or handwritten ledgers. This leads to pricing errors, duplicate entries, no image tracking, and zero access control — anyone with the spreadsheet can modify records.

### Solution

PocketPhone provides a web-based inventory management system with a dedicated admin panel. Retailers can add, edit, and delete products with images through a clean interface. A public-facing showcase page displays the current inventory to customers automatically.

### Architecture

The system follows a traditional PHP MVC-like pattern:

```mermaid
graph TD
A[Browser] -->|HTTP| B[index.php — Product Showcase]
A -->|Admin Login| C[admin/login.php]
C -->|Session Auth| D[auth_check.php]
D --> E[admin/index.php — Dashboard]
E --> F[add_product.php]
E --> G[edit_product.php]
E --> H[delete_product.php]
Comment on lines +98 to +102
Copy link

Copilot AI Mar 8, 2026

Choose a reason for hiding this comment

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

In the Mermaid architecture diagram, auth_check.php and the CRUD pages are referenced without the admin/ prefix, but they live under admin/ in the repo. Updating these node labels/links to admin/auth_check.php, admin/add_product.php, etc. will prevent confusion and broken references.

Suggested change
C -->|Session Auth| D[auth_check.php]
D --> E[admin/index.php — Dashboard]
E --> F[add_product.php]
E --> G[edit_product.php]
E --> H[delete_product.php]
C -->|Session Auth| D[admin/auth_check.php]
D --> E[admin/index.php — Dashboard]
E --> F[admin/add_product.php]
E --> G[admin/edit_product.php]
E --> H[admin/delete_product.php]

Copilot uses AI. Check for mistakes.
F & G & H -->|Prepared Statements| I[(MySQL)]
F & G -->|Image Upload| J[uploads/]
I --> B
```

- **Authentication layer** (`auth_check.php`) guards all admin routes via PHP sessions
- **Database layer** (`db_config.php`) centralizes connection logic with UTF-8 support
- **File uploads** are stored on disk in `uploads/` with validation
Comment on lines +108 to +110
Copy link

Copilot AI Mar 8, 2026

Choose a reason for hiding this comment

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

These bullets reference auth_check.php and db_config.php without the admin/ path, but the actual files are admin/auth_check.php and admin/db_config.php (and public index.php includes admin/db_config.php). Consider updating the paths here to match the project structure.

Copilot uses AI. Check for mistakes.

### Security Considerations

- Passwords are hashed with `password_hash()` (bcrypt) — never stored as plaintext
- All SQL queries use prepared statements to prevent injection
- Output is escaped with `htmlspecialchars()` to prevent XSS
- Session-based authentication with proper logout (session destruction)
- File upload validation checks type and size before storage

### Lessons Learned

- **Separation of concerns**: Even without a framework, keeping auth, config, and CRUD in separate files made the codebase manageable
- **Prepared statements from day one**: Retrofitting SQL injection prevention is harder than building it in
- **Bcrypt over MD5/SHA**: Using PHP's built-in `password_hash()` is simpler AND more secure than rolling custom hashing
- **Image storage**: Storing on disk with DB references is simpler than BLOB storage for a small-scale app

See [docs/architecture.md](docs/architecture.md) for a deeper dive into the system components.

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
Expand Down
108 changes: 108 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# PocketPhone — Architecture

## System Overview

PocketPhone is a PHP/MySQL inventory management application with two interfaces:

1. **Public showcase** (`index.php`) — read-only product listing for customers
2. **Admin panel** (`admin/`) — authenticated CRUD interface for store managers

## Component Diagram

```mermaid
graph LR
subgraph Public
A[index.php]
end
subgraph Admin Panel
B[login.php] --> C[auth_check.php]
C --> D[index.php]
C --> E[add_product.php]
C --> F[edit_product.php]
C --> G[delete_product.php]
Comment on lines +18 to +22
Copy link

Copilot AI Mar 8, 2026

Choose a reason for hiding this comment

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

In the component diagram, login.php is shown flowing into auth_check.php, but admin/login.php does not include auth_check.php; instead, admin pages include auth_check.php and redirect unauthenticated users to login.php. Update the arrows/nodes to reflect the actual include/redirect flow so readers don’t infer login.php depends on auth_check.php.

Suggested change
B[login.php] --> C[auth_check.php]
C --> D[index.php]
C --> E[add_product.php]
C --> F[edit_product.php]
C --> G[delete_product.php]
B[login.php]
C[auth_check.php]
D[index.php]
E[add_product.php]
F[edit_product.php]
G[delete_product.php]
D & E & F & G --> C
C --> B

Copilot uses AI. Check for mistakes.
end
subgraph Storage
H[(MySQL)]
I[uploads/]
end
subgraph Config
J[db_config.php]
K[hashed.php]
end
A --> J --> H
D & E & F & G --> J
E & F --> I
```

## Data Flow

### Product Creation

1. Admin authenticates via `login.php` → session created
2. `auth_check.php` validates session on every admin page load
3. Admin fills form on `add_product.php` (name, price, description, image)
4. Server validates input, moves uploaded image to `uploads/`
Comment on lines +43 to +44
Copy link

Copilot AI Mar 8, 2026

Choose a reason for hiding this comment

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

The “Product Creation” step list mentions a description field, but admin/add_product.php only collects/stores name, condition, price, and image (it inserts into condition_desc and image_path). Please align the documentation with the actual form fields/DB columns.

Copilot uses AI. Check for mistakes.
5. Prepared INSERT statement writes to MySQL `products` table
6. Admin is redirected to dashboard with success message

### Product Display (Public)

1. `index.php` queries all products via `db_config.php` connection
2. Results are looped and rendered as HTML cards with escaped output
3. Product images are served from `uploads/` directory

## Authentication Flow

```mermaid
sequenceDiagram
participant U as User
participant L as login.php
participant A as auth_check.php
participant D as Dashboard

U->>L: POST credentials
L->>L: password_verify(input, hash)
alt Valid
L->>L: session_start(), set $_SESSION
L->>D: redirect to admin/index.php
D->>A: include auth_check.php
A->>A: verify $_SESSION exists
A->>D: allow access
else Invalid
L->>U: error message
end
```

## Database Schema

The application uses a single `products` table:

| Column | Type | Description |
|--------|------|-------------|
| id | INT AUTO_INCREMENT | Primary key |
| name | VARCHAR | Product name |
| price | DECIMAL | Product price |
| description | TEXT | Product details |
| image | VARCHAR | Filename in uploads/ |
Comment on lines +85 to +86
Copy link

Copilot AI Mar 8, 2026

Choose a reason for hiding this comment

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

This products table schema doesn’t match the code: the app reads/writes condition_desc and image_path (and does not use description or image columns). Please update the schema table to reflect the actual column names used by the application.

Suggested change
| description | TEXT | Product details |
| image | VARCHAR | Filename in uploads/ |
| condition_desc | TEXT | Product condition/details |
| image_path | VARCHAR | Image path/filename in uploads/ |

Copilot uses AI. Check for mistakes.

Admin credentials are stored in a separate `users` table with bcrypt-hashed passwords.
Copy link

Copilot AI Mar 8, 2026

Choose a reason for hiding this comment

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

The admin credentials table name appears to be admins (see the query in admin/login.php), not users. Please update this line so the documentation matches the implementation/database naming.

Suggested change
Admin credentials are stored in a separate `users` table with bcrypt-hashed passwords.
Admin credentials are stored in a separate `admins` table with bcrypt-hashed passwords.

Copilot uses AI. Check for mistakes.

## Security Architecture

| Threat | Mitigation |
|--------|-----------|
| SQL Injection | Prepared statements (`mysqli::prepare`) throughout |
| XSS | `htmlspecialchars()` on all output |
| Session Hijacking | Session regeneration on login |
| Brute Force | Password hashing with bcrypt (`password_hash`) |
| File Upload Attacks | Type/size validation before `move_uploaded_file()` |
Comment on lines +95 to +98
Copy link

Copilot AI Mar 8, 2026

Choose a reason for hiding this comment

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

Several items in the security threat table don’t match the current implementation: there is no session ID regeneration on login, and hashing passwords is not a brute-force mitigation (there’s no rate limiting/lockout). Also, output escaping is not applied to all rendered user-controlled values (e.g., some form fields echo raw values). Please adjust the mitigations to reflect what the code actually does (or implement the missing defenses).

Suggested change
| XSS | `htmlspecialchars()` on all output |
| Session Hijacking | Session regeneration on login |
| Brute Force | Password hashing with bcrypt (`password_hash`) |
| File Upload Attacks | Type/size validation before `move_uploaded_file()` |
| XSS | `htmlspecialchars()` on public product listing; some admin outputs still echo raw values |
| Session Hijacking | Session-based access control via `auth_check.php`; no session ID regeneration on login |
| Brute Force | Credentials stored with bcrypt (`password_hash`); no login rate limiting or lockout implemented |
| File Upload Attacks | Images uploaded via `move_uploaded_file()`; additional type/size validation required |

Copilot uses AI. Check for mistakes.
| Direct File Access | `auth_check.php` included at top of every admin page |

## Deployment

The application runs on any LAMP/WAMP/XAMPP stack:

1. Copy files to web server document root
2. Create MySQL database and import schema
3. Update `admin/db_config.php` with database credentials
4. Ensure `uploads/` directory is writable by the web server