Implemented a comprehensive Role-Based Access Control system following GeeksforGeeks RBAC best practices, with role hierarchy: Admin > Editor > Viewer. Added share token functionality allowing admins to generate time-limited, permission-scoped access links.
Changed all role references from "Owner" to "Admin" for consistency and clarity across the entire system.
- schema.sql - UserDashboards and PendingInvitations tables
- seed.sql - Default role assignments
- All middleware files
- All route files
- All controller files
- Frontend JavaScript files
- README.md
CREATE TABLE ShareTokens (
ShareTokenId INT IDENTITY(1,1) PRIMARY KEY,
DashboardId INT NOT NULL FOREIGN KEY REFERENCES Dashboards(DashboardId) ON DELETE CASCADE,
CreatedBy INT NOT NULL FOREIGN KEY REFERENCES Users(UserId),
Token NVARCHAR(255) UNIQUE NOT NULL, -- Unique share token
Role NVARCHAR(50) DEFAULT 'Viewer', -- 'Admin', 'Editor', 'Viewer'
ExpiresAt DATETIME, -- NULL means no expiration
IsActive BIT DEFAULT 1,
CreatedAt DATETIME DEFAULT GETDATE(),
RevokedAt DATETIME NULL,
AccessCount INT DEFAULT 0 -- Track usage
);-
createShareToken(dashboardId, createdBy, role, expirationDays)- Generates unique share tokens with crypto.randomBytes
- Supports optional expiration (7 days by default)
- Returns token metadata
-
getShareTokens(dashboardId)- Retrieves all share tokens for a dashboard
- Shows active/revoked status
-
getShareTokenInfo(token)- Validates and retrieves token information
- Increments access count on retrieval
- Returns dashboard name and role
-
revokeShareToken(shareTokenId)- Deactivates tokens immediately
- Sets RevokedAt timestamp
-
updateShareTokenRole(shareTokenId, newRole)- Allows admins to change token permissions
- Supports role changes: Viewer, Editor, Admin
createShareToken()- POST/api/dashboards/:dashboardId/share-tokensgetShareTokens()- GET/api/dashboards/:dashboardId/share-tokensupdateShareTokenRole()- PUT/api/dashboards/share-tokens/:shareTokenId/rolerevokeShareToken()- DELETE/api/dashboards/share-tokens/:shareTokenId/revoke
All middleware files updated to use 'Admin' instead of 'Owner':
- dashboardRoutes.js - All admin-only endpoints check for 'Admin' role + new share token routes
- taskRoutes.js - Board/Task creation/editing requires 'Admin' or 'Editor'
loadShareTokens()- Fetches active share tokens for displayrenderShareTokens(tokens)- Renders token list with copy-to-clipboardcopyToClipboard(text, element)- Copies share link with visual feedbackcreateShareToken()- Generates new share tokenupdateShareTokenRole(shareTokenId, newRole)- Changes token permissionsrevokeShareToken(shareTokenId)- Deactivates token with confirmationcheckAndShowViewingModeIfNeeded()- Checks user role and shows viewing modeshowViewingModeOverlay()- Displays yellow banner at top of pagedisableEditingForViewers()- Disables all edit buttons and inputs for viewers
- Share Links Tab - New navigation item
- Share Token Creator - Role selector + expiration input + generate button
- Active Share Links List - Displays tokens with:
- Full share link with click-to-copy
- Role badge
- Expiration date
- Usage count
- Role updater dropdown
- Revoke button
- Viewing Mode Banner - Yellow overlay banner for viewers showing:
- 🔒 Icon
- "You are in viewing mode" heading
- "You are unable to make changes to this document." message
Added comprehensive styling for:
- Share token creator form
- Share token list items with role badges
- Viewing mode overlay banner
- Responsive flex layout for token actions
- Dark theme support for viewing mode
- Changed
currentUserRole === 'Owner'tocurrentUserRole === 'Admin' - Disabled UI elements for non-admin users
- Updated role dropdown options
- Changed "Owner" to "Admin" in role display
- Changed "Transfer ownership" to "Transfer admin role"
- Invite role selector includes 'admin' option
| Action | Admin | Editor | Viewer |
|---|---|---|---|
| View Dashboard | ✅ | ✅ | ✅ |
| View Boards/Tasks | ✅ | ✅ | ✅ |
| Create/Edit Tasks | ✅ | ✅ | ❌ |
| Edit Dashboard Settings | ✅ | ❌ | ❌ |
| Manage Collaborators | ✅ | ❌ | ❌ |
| Change User Roles | ✅ | ❌ | ❌ |
| Create Share Tokens | ✅ | ❌ | ❌ |
| Modify Share Tokens | ✅ | ❌ | ❌ |
| Delete Dashboard | ✅ | ❌ | ❌ |
/accept-share?token=<32-byte-hex-string>
- Time-Limited: Optional expiration date (can be indefinite)
- Revocable: Admins can revoke tokens anytime
- Usage Tracking: Counts how many times token was accessed
- Role-Scoped: Tokens grant only the specified role's permissions
- One-Per-Link: Each token generates a unique shareable URL
- Unique 256-bit tokens (32 bytes of random data)
- Active/Revoked status tracking
- Expiration enforcement
- Access logging via AccessCount
- Only admins can create/manage tokens
- Token validation on each use
-
When a viewer accesses dashboard settings, they see:
- Yellow banner at top: "🔒 You are in viewing mode"
- Subtitle: "You are unable to make changes to this document."
-
All edit controls are disabled:
- Update name button (disabled)
- Transfer admin role button (disabled)
- Invite collaborator button (disabled)
- Create share token button (disabled)
- Delete dashboard button (disabled)
- All text inputs (disabled)
- All role selection dropdowns (disabled)
- Visibility radio buttons (disabled)
- Checks current user's role against collaborators list
- Only viewers trigger the protection
- Non-intrusive banner (not modal/popup)
- Seamless integration with existing UI
✅ Centralized Role Definition - Admin, Editor, Viewer roles defined consistently ✅ Granular Control - Both page-level (dashboard access) and component-level (buttons/inputs) ✅ Middleware-Based Enforcement - Backend validates roles before processing requests ✅ JWT Integration - Roles embedded in user tokens ✅ Scalable & Maintainable - Easy to add new roles or modify permissions ✅ Better UX - Users only see features they can use ✅ Consistency - Enforced at frontend, middleware, and backend API levels ✅ Enterprise-Ready - Supports complex access patterns via share tokens
- Back up existing database
- Run updated
schema.sqlto create ShareTokens table - Run
seed.sqlto update test data with 'Admin' role - Verify UserDashboards and PendingInvitations tables have role values of 'Admin', 'Editor', or 'Viewer'
POST /api/dashboards/:dashboardId/share-tokens - Create share token
GET /api/dashboards/:dashboardId/share-tokens - List tokens
PUT /api/dashboards/share-tokens/:shareTokenId/role - Update token role
DELETE /api/dashboards/share-tokens/:shareTokenId/revoke - Revoke token
PUT /api/dashboards/:dashboardId - Admin only
DELETE /api/dashboards/:dashboardId - Admin only
POST /api/dashboards/:dashboardId/users - Admin only
PUT /api/dashboards/:dashboardId/users/:userId/role - Admin only
DELETE /api/dashboards/:dashboardId/users/:userId - Admin only
Backend:
- schema.sql
- seed.sql
- models/dashboardModel.js
- controllers/dashboardController.js
- middleware/permissionCheck.js
- middleware/boardPermissionCheck.js
- middleware/taskPermissionCheck.js
- routes/dashboardRoutes.js
- routes/taskRoutes.js
Frontend:
- dashboard-settings/dashboard-settings.html
- dashboard-settings/dashboard-settings.js
- dashboard-settings/dashboard-settings.css
- collaborators/collaborators.js
Documentation:
- README.md
-
Admin User: Should be able to:
- Create and manage share tokens
- Change token permissions
- Revoke tokens
- See all management options
-
Editor User: Should be able to:
- View dashboard and collaborate
- Not see share token management
- Edit/create tasks but not manage collaborators
-
Viewer User: Should be able to:
- View dashboard content
- See yellow "viewing mode" banner
- All edit controls disabled
- Cannot access management sections
-
Share Token: Should be able to:
- Access dashboard with specified role
- Increment access counter
- Respect expiration date
- Work after revocation (should fail)
- Share token templates (pre-configured role + expiration sets)
- Bulk token operations (create multiple tokens at once)
- Token activity logs (detailed access history)
- Email notifications when tokens are created/revoked
- Custom token names and descriptions
- Conditional access (IP whitelist, device fingerprinting)
- Token refresh mechanism for extended access
- All changes follow RBAC security best practices
- Role naming is consistent across frontend and backend
- Viewing mode protection prevents accidental modifications
- Share tokens provide flexible, time-limited access without email invitations
- System maintains backward compatibility with existing invitation system