Skip to content
Draft
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,4 @@
- [Backend](docs/backend/backend.md)
- [Frontend](docs/frontend/frontend.md)
- [API](docs/api/api.md)
- [Role Enforcement Testing](docs/ROLE_ENFORCEMENT_TESTING.md)
3 changes: 2 additions & 1 deletion backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"scripts": {
"dev": "nodemon src/server.js",
"start": "node src/server.js",
"seed": "node src/seed/seed.js"
"seed": "node src/seed/seed.js",
"seed:test-users": "node src/seed/create-test-users.js"
},
"keywords": [],
"author": "",
Expand Down
84 changes: 84 additions & 0 deletions backend/src/seed/create-test-users.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#!/usr/bin/env node
/**
* Script to create test users with different roles for testing role enforcement
* Usage: node create-test-users.js
*/

require("dotenv").config();
const bcrypt = require("bcrypt");
const { loadEnv } = require("../config/env");
const { connectDB } = require("../config/db");
const models = require("../models");

const TEST_USERS = [
{
name: "Admin User",
email: "admin@tasky.local",
password: "password",
role: "admin"
},
{
name: "Member User",
email: "member@tasky.local",
password: "password",
role: "member"
},
{
name: "Viewer User",
email: "viewer@tasky.local",
password: "password",
role: "viewer"
}
];

async function createTestUsers() {
try {
const env = loadEnv();
await connectDB(env.mongoUri);

console.log("🧹 Cleaning up old test users...");

// Remove existing test users
for (const user of TEST_USERS) {
await models.User.deleteOne({ email: user.email });
}

console.log("👥 Creating test users...\n");

for (const userData of TEST_USERS) {
const salt = await bcrypt.genSalt(10);
const hashedPassword = await bcrypt.hash(userData.password, salt);

const result = await models.User.collection.insertOne({
name: userData.name,
email: userData.email,
password: hashedPassword,
role: userData.role,
createdAt: new Date(),
updatedAt: new Date(),
__v: 0
});

console.log(`✅ Created ${userData.role.toUpperCase()} user:`);
console.log(` Email: ${userData.email}`);
console.log(` Password: ${userData.password}`);
console.log(` Role: ${userData.role}`);
console.log(` ID: ${result.insertedId}\n`);
}

console.log("🎉 Test users created successfully!");
console.log("\nYou can now test role enforcement with these credentials:");
console.log("─".repeat(60));
TEST_USERS.forEach(user => {
console.log(`${user.role.toUpperCase().padEnd(10)} | ${user.email.padEnd(30)} | password`);
});
console.log("─".repeat(60));

process.exit(0);
} catch (err) {
console.error("❌ Error creating test users:", err);
process.exit(1);
}
}

createTestUsers();
181 changes: 181 additions & 0 deletions docs/IMPLEMENTATION_SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
# Role Enforcement UI/UX Implementation - Summary

## Overview
This implementation adds comprehensive role-based access control (RBAC) to the Tasky application's user interface. The system leverages the existing backend role infrastructure to provide granular permission controls across the frontend.

## Implementation Summary

### ✅ Completed Features

#### 1. Authentication Utility Module
**File:** `frontend/src/utils/auth.js`

Created a centralized module for role-based permission checking:
- `getCurrentUser()` - Retrieves user from localStorage
- `getUserRole()` - Gets current user's role
- `isAdmin()` - Checks for admin role
- `isMember()` - Checks for member or admin role
- `isViewer()` - Checks for any authenticated role
- `hasRole(role)` - Hierarchical role checking

**Role Hierarchy:** Admin (3) > Member (2) > Viewer (1)

#### 2. UI Components Updated

##### Navbar Component
- **Added:** Role badge displaying current user role
- **Colors:** Red (admin), Blue (member), Gray (viewer)
- **Location:** Next to notifications icon

##### BoardsList Page
- **Replaced:** Hardcoded `isAdmin = true` with actual role checking
- **Create Board Button:** Visible only to members and admins
- **Delete Board Icon:** Visible only to admins

##### BoardViewPage
- **Replaced:** Hardcoded `isAdmin = true` with actual role checking
- **Add Column Button:** Visible only to members and admins
- **Delete Column Icon:** Visible only to admins
- **Add Card Button:** Hidden for viewers (display: none)

##### EditTicketModal
- **Form Fields:** All fields disabled for viewers (title, description, priority, status, assignee)
- **Save Changes Button:** Hidden for viewers
- **Delete Task Button:** Hidden for viewers
- **Read-only Mode:** Viewers can view ticket details but cannot modify

##### CommentThread
- **Comment Input:** Hidden for viewers
- **Send Button:** Hidden for viewers
- **Delete Comment:** Visible only to comment author or admins (already implemented)

### 📋 Permission Matrix

| Feature | Viewer | Member | Admin |
|---------|--------|--------|-------|
| **Boards** |
| View Boards | ✅ | ✅ | ✅ |
| Create Boards | ❌ | ✅ | ✅ |
| Delete Boards | ❌ | ❌ | ✅ |
| **Columns** |
| View Columns | ✅ | ✅ | ✅ |
| Create Columns | ❌ | ✅ | ✅ |
| Delete Columns | ❌ | ❌ | ✅ |
| **Tickets/Tasks** |
| View Tickets | ✅ | ✅ | ✅ |
| Create Tickets | ❌ | ✅ | ✅ |
| Edit Tickets | ❌ | ✅ | ✅ |
| Delete Tickets | ❌ | ✅ | ✅ |
| **Comments** |
| View Comments | ✅ | ✅ | ✅ |
| Add Comments | ❌ | ✅ | ✅ |
| Delete Own Comments | ❌ | ✅ | ✅ |
| Delete Any Comment | ❌ | ❌ | ✅ |

### 🔧 Backend Support

The backend already had comprehensive role enforcement in place:
- **User Model:** Has `role` field with enum ['admin', 'member', 'viewer']
- **JWT Token:** Includes role in payload
- **Middleware:** `requireAuth`, `requireMember`, `requireAdmin`
- **Role Helpers:** `isAdmin()`, `isMember()`, `hasRoleLevel()`

This implementation leverages these existing backend features without requiring any backend changes.

### 📚 Documentation

#### Created Files:
1. **`docs/ROLE_ENFORCEMENT_TESTING.md`**
- 11 comprehensive test cases
- Step-by-step testing instructions
- Permission matrix
- Automated testing script example

2. **`backend/src/seed/create-test-users.js`**
- Script to create test users with different roles
- Creates admin, member, and viewer users
- Usage: `npm run seed:test-users`

#### Updated Files:
1. **`README.md`**
- Added link to role enforcement testing documentation

### 🔒 Security Considerations

1. **Frontend-Only Restrictions:** UI restrictions are for user experience. True security is enforced by backend middleware.

2. **Token-Based Roles:** Role information is stored in JWT tokens which expire after 7 days.

3. **Role Updates:** Users must re-login after role changes to see updated permissions.

4. **No Security Vulnerabilities:** CodeQL scan found 0 security issues.

### 🧪 Testing

#### Manual Testing Required:
To fully test the role enforcement:

1. **Create Test Users:**
```bash
cd backend
npm run seed:test-users
```

2. **Test with Each Role:**
- Login as admin@tasky.local (password: password)
- Login as member@tasky.local (password: password)
- Login as viewer@tasky.local (password: password)

3. **Verify Permissions:**
- Check navbar role badge
- Try creating boards/columns/tickets
- Try deleting items
- Try editing tickets
- Try adding comments

4. **Test Backend Enforcement:**
- Use curl/Postman to attempt unauthorized actions
- Verify 403 Forbidden responses

See `docs/ROLE_ENFORCEMENT_TESTING.md` for detailed test cases.

### 📊 Code Quality

- ✅ **Linting:** All files pass ESLint checks
- ✅ **Build:** Frontend builds successfully without warnings
- ✅ **Code Review:** All review comments addressed
- ✅ **Security Scan:** CodeQL found 0 vulnerabilities
- ✅ **Consistency:** Consistent use of role checking utilities

### 🎯 Impact

**Files Modified:** 7
**Files Created:** 3
**Lines Added:** ~450
**Lines Modified:** ~50

**Key Benefits:**
1. **Better UX:** Users only see features they can use
2. **Clear Permissions:** Role badge shows user's permission level
3. **Security:** Frontend restrictions complement backend enforcement
4. **Maintainable:** Centralized role checking logic
5. **Testable:** Comprehensive testing documentation

### 🚀 Next Steps (Post-Implementation)

1. **Create Test Users:** Run `npm run seed:test-users` in backend
2. **Manual Testing:** Follow the testing guide
3. **User Feedback:** Gather feedback on role restrictions
4. **Iteration:** Adjust permissions based on user needs

### 📝 Notes

- The backend role system was already well-implemented
- This PR focuses purely on frontend UI/UX enforcement
- No database schema changes required
- No API changes required
- Backward compatible with existing user accounts

## Conclusion

This implementation successfully adds role-based UI/UX enforcement to the Tasky application, making the user interface match the backend's permission system. Users now have a clear visual indication of their role and can only interact with features they have permission to use.
Loading