This repository was archived by the owner on Mar 29, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Codebase Flowchart
Ritaban Ghosh edited this page Jan 29, 2026
·
6 revisions
This document provides a detailed low-level flowchart of the entire EduDrive codebase, covering all major components, data flows, and interactions.
graph TB
subgraph "Client Applications"
WebClient[Web Client - React + Vite - Port 3000]
AndroidApp[Android App - Capacitor]
end
subgraph "Admin Application"
AdminPanel[Admin Dashboard - React + Vite - Port 3001]
end
subgraph "Backend Server"
ExpressAPI[Express.js API - Port 5000]
SocketIO[Socket.IO Server - Real-time Updates]
end
subgraph "Database"
MongoDB[(MongoDB Atlas - Database)]
end
subgraph "External Services"
GoogleOAuth[Google OAuth 2.0]
GoogleDrive[Google Drive API - PDF Storage]
GoogleSheets[Google Sheets API - User Approval List]
end
WebClient -->|HTTP/HTTPS| ExpressAPI
AndroidApp -->|HTTP/HTTPS| ExpressAPI
AdminPanel -->|HTTP/HTTPS| ExpressAPI
WebClient -.->|WebSocket| SocketIO
AndroidApp -.->|WebSocket| SocketIO
AdminPanel -.->|WebSocket| SocketIO
ExpressAPI --> MongoDB
ExpressAPI --> GoogleOAuth
ExpressAPI --> GoogleDrive
ExpressAPI --> GoogleSheets
SocketIO -.->|Broadcast Updates| WebClient
SocketIO -.->|Broadcast Updates| AndroidApp
flowchart TD
Start([server.js starts]) --> LoadEnv[Load Environment Variables]
LoadEnv --> InitExpress[Initialize Express App]
InitExpress --> ConfigSecurity[Configure Security - Helmet, CORS, Rate Limiting]
ConfigSecurity --> ConfigMiddleware[Configure Middleware - Morgan, Compression, Body Parser]
ConfigMiddleware --> ConnectDB[Connect to MongoDB]
ConnectDB --> MountRoutes[Mount API Routes]
MountRoutes --> AuthRoutes[/api/auth]
MountRoutes --> PDFRoutes[/api/pdfs]
MountRoutes --> FolderRoutes[/api/folders]
MountRoutes --> UserRoutes[/api/users]
MountRoutes --> AdminRoutes[/api/admin]
MountRoutes --> AccessTagRoutes[/api/access-tags]
MountRoutes --> CreateHTTPServer[Create HTTP Server]
CreateHTTPServer --> InitSocketIO[Initialize Socket.IO]
InitSocketIO --> SetupSocketEvents[Setup Socket Event Handlers]
SetupSocketEvents --> StartServer[Start Server on Port 5000]
StartServer --> Ready([Server Ready])
classDiagram
class User {
+String email
+String password (hashed)
+String name
+String department
+Number year
+Number semester
+String role (admin/client)
+String googleId
+String picture
+String deviceId
+Date lastLogin
+Boolean isActive
+Boolean isLocked
+Number loginAttempts
+Array accessTags
+String loginMethod
+comparePassword()
+incLoginAttempts()
+resetLoginAttempts()
}
class PDF {
+String title
+String description
+String fileId (Google Drive)
+String mimeType
+Number size
+String department
+Number year
+Number semester
+String category
+String uploadedBy
+Date uploadedAt
+Number viewCount
+Array accessTags
+String folderId
+String webViewLink
+String thumbnailLink
}
class Folder {
+String name
+String description
+String gdriveId
+String department
+Number year
+Number semester
+String category
+String parentFolder
+Array subfolders
+Number pdfCount
+Array accessTags
+Date createdAt
+Date updatedAt
}
class AccessLog {
+ObjectId userId
+String action
+ObjectId pdfId
+String ipAddress
+String userAgent
+String deviceId
+Object metadata
+Date timestamp
+logAccess() static
}
class AccessTag {
+String name
+String description
+String color
+Boolean isActive
+Date createdAt
+Date updatedAt
}
class Annotation {
+ObjectId userId
+ObjectId pdfId
+String content
+Number page
+Object position
+Date createdAt
}
User "1" --> "*" AccessLog : creates
User "1" --> "*" Annotation : creates
PDF "1" --> "*" AccessLog : tracked by
PDF "1" --> "*" Annotation : has
PDF "*" --> "1" Folder : belongs to
User "*" --> "*" AccessTag : has
PDF "*" --> "*" AccessTag : requires
Folder "*" --> "*" AccessTag : requires
flowchart TD
Start([User Action]) --> LoginType{Login Type?}
LoginType -->|Email/Password| EmailLogin[POST /api/auth/login]
LoginType -->|Register| Register[POST /api/auth/register]
LoginType -->|Google OAuth| GoogleLogin[Google OAuth Flow]
LoginType -->|Admin| AdminLogin[POST /api/auth/admin-login]
EmailLogin --> ValidateCredentials{Valid - Credentials?}
ValidateCredentials -->|No| ReturnError[Return 401 Error]
ValidateCredentials -->|Yes| CheckActive{Account - Active?}
CheckActive -->|No| ReturnDeactivated[Return 401 Deactivated]
CheckActive -->|Yes| CheckLocked{Account - Locked?}
CheckLocked -->|Yes| ReturnLocked[Return 423 Locked]
CheckLocked -->|No| GenerateDeviceID[Generate Device ID]
Register --> ValidateInput{Valid - Input?}
ValidateInput -->|No| ReturnValidationError[Return 400 Error]
ValidateInput -->|Yes| CheckExisting{User - Exists?}
CheckExisting -->|Yes| ReturnConflict[Return 409 Conflict]
CheckExisting -->|No| CreateUser[Create User in DB]
CreateUser --> GenerateDeviceID
AdminLogin --> CheckEnvCreds{Valid Admin - Credentials?}
CheckEnvCreds -->|No| LogFailedAttempt[Log Failed Attempt]
LogFailedAttempt --> ReturnError
CheckEnvCreds -->|Yes| GenerateAdminToken[Generate Admin JWT - 24h expiry]
GenerateAdminToken --> ReturnAdminToken[Return Admin Token]
GenerateDeviceID --> GenerateJWT[Generate JWT Token - 7 day expiry]
GenerateJWT --> UpdateUserRecord[Update User Record - deviceId, lastLogin]
UpdateUserRecord --> LogAccess[Log Access to AccessLog]
LogAccess --> ReturnToken[Return JWT + User Data]
GoogleLogin --> InitiateOAuth[GET /api/auth/google]
InitiateOAuth --> RedirectGoogle[Redirect to Google]
RedirectGoogle --> UserAuthorizes[User Authorizes]
UserAuthorizes --> GoogleCallback[GET /api/auth/google/callback]
GoogleCallback --> ExchangeCode[Exchange Code for Tokens]
ExchangeCode --> VerifyToken[Verify ID Token]
VerifyToken --> CheckApproved{User in - Approved List?}
CheckApproved -->|No| ReturnAccessDenied[Return Access Denied]
CheckApproved -->|Yes| CreateOrUpdateUser[Create/Update User]
CreateOrUpdateUser --> GenerateDeviceID
sequenceDiagram
participant Client
participant Backend
participant Google
participant GoogleSheets
participant MongoDB
Client->>Backend: GET /api/auth/google?platform=web/android
Backend->>Backend: Generate OAuth URL with state
Backend->>Client: Redirect to Google OAuth
Client->>Google: User authorizes application
Google->>Backend: GET /api/auth/google/callback?code=xxx&state=xxx
Backend->>Google: Exchange code for tokens
Google->>Backend: Return access_token & id_token
Backend->>Google: Verify ID token
Google->>Backend: Return user payload (email, name, picture)
Backend->>GoogleSheets: Check if email in approved list
GoogleSheets->>Backend: Return approval status + user data
alt User Not Approved
Backend->>Client: Redirect with error
else User Approved
Backend->>MongoDB: Create or update user
MongoDB->>Backend: User saved
Backend->>Backend: Generate JWT token
Backend->>Backend: Set HTTP-only cookies
Backend->>MongoDB: Log access
Backend->>Client: Redirect to app-login-success with token
end
flowchart TD
Request([API Request]) --> ExtractToken[Extract Token from - Authorization Header]
ExtractToken --> TokenExists{Token - Exists?}
TokenExists -->|No| Return401[Return 401 Unauthorized]
TokenExists -->|Yes| VerifyJWT[Verify JWT Signature]
VerifyJWT --> ValidSignature{Valid - Signature?}
ValidSignature -->|No| ReturnInvalid[Return 401 Invalid Token]
ValidSignature -->|Yes| CheckExpiry{Token - Expired?}
CheckExpiry -->|Yes| ReturnExpired[Return 401 Token Expired]
CheckExpiry -->|No| ExtractPayload[Extract userId, role, deviceId]
ExtractPayload --> FetchUser[Fetch User from MongoDB]
FetchUser --> UserExists{User - Exists?}
UserExists -->|No| Return401
UserExists -->|Yes| CheckUserActive{User - Active?}
CheckUserActive -->|No| Return401
CheckUserActive -->|Yes| AttachUser[Attach User to req.user]
AttachUser --> CheckRole{Admin - Required?}
CheckRole -->|Yes| IsAdmin{User is - Admin?}
CheckRole -->|No| ProceedRequest[Proceed with Request]
IsAdmin -->|No| Return403[Return 403 Forbidden]
IsAdmin -->|Yes| ProceedRequest
ProceedRequest --> ExecuteHandler[Execute Route Handler]
flowchart TD
Start([Admin Uploads PDF]) --> UploadRequest[POST /api/pdfs/upload]
UploadRequest --> AuthCheck{Authenticated - & Admin?}
AuthCheck -->|No| Return403[Return 403 Forbidden]
AuthCheck -->|Yes| ValidateInput{Valid PDF - Metadata?}
ValidateInput -->|No| Return400[Return 400 Bad Request]
ValidateInput -->|Yes| CheckFolder{Folder - Exists?}
CheckFolder -->|No| CreateFolder[Create Folder in DB]
CheckFolder -->|Yes| UploadToGDrive[Upload File to Google Drive]
CreateFolder --> UploadToGDrive
UploadToGDrive --> SetPermissions[Set Google Drive Permissions - Anyone with link can view]
SetPermissions --> GetFileMetadata[Get File Metadata - fileId, webViewLink, size]
GetFileMetadata --> CreatePDFRecord[Create PDF Record in MongoDB]
CreatePDFRecord --> UpdateFolderCount[Update Folder PDF Count]
UpdateFolderCount --> EmitSocketEvent[Emit Socket.IO Event - pdf:updated]
EmitSocketEvent --> ReturnSuccess[Return PDF Data]
flowchart TD
Start([User Views PDF]) --> GetPDFList[GET /api/pdfs?filters]
GetPDFList --> AuthCheck{Authenticated?}
AuthCheck -->|No| Return401[Return 401 Unauthorized]
AuthCheck -->|Yes| ApplyFilters[Apply Filters - department, year, semester, tags]
ApplyFilters --> CheckAccessTags{User has - Access Tags?}
CheckAccessTags -->|No| FilterByDeptYear[Filter by Department & Year]
CheckAccessTags -->|Yes| FilterByTags[Filter by Access Tags]
FilterByDeptYear --> QueryDB[Query MongoDB]
FilterByTags --> QueryDB
QueryDB --> ReturnPDFList[Return PDF List]
ReturnPDFList --> UserSelectsPDF[User Selects PDF]
UserSelectsPDF --> GetPDFDetails[GET /api/pdfs/:id]
GetPDFDetails --> AuthCheck2{Authenticated?}
AuthCheck2 -->|No| Return401
AuthCheck2 -->|Yes| CheckAccess{User has - Access?}
CheckAccess -->|No| Return403[Return 403 Forbidden]
CheckAccess -->|Yes| IncrementViewCount[Increment View Count]
IncrementViewCount --> LogPDFAccess[Log PDF Access]
LogPDFAccess --> GetSignedURL[Generate Signed Google Drive URL]
GetSignedURL --> ReturnPDFData[Return PDF Data + Signed URL]
ReturnPDFData --> RenderPDF[Render PDF in SecurePDFViewer]
RenderPDF --> ApplySecurity[Apply Security Measures - No download, print, share]
sequenceDiagram
participant Client
participant Backend
participant GoogleDrive
Client->>Backend: GET /api/pdfs/:id/stream
Backend->>Backend: Authenticate user
Backend->>Backend: Check PDF access permissions
Backend->>GoogleDrive: Request PDF file stream
GoogleDrive->>Backend: Stream PDF chunks
loop Stream chunks
Backend->>Client: Forward PDF chunk
end
GoogleDrive->>Backend: End of stream
Backend->>Client: Complete response
Backend->>Backend: Log access
flowchart TD
Start([Admin Manages Folders]) --> Action{Action Type?}
Action -->|Create| CreateFolder[POST /api/folders]
Action -->|Update| UpdateFolder[PUT /api/folders/:id]
Action -->|Delete| DeleteFolder[DELETE /api/folders/:id]
Action -->|Sync| SyncGDrive[GET /api/folders/gdrive]
CreateFolder --> ValidateInput{Valid - Input?}
ValidateInput -->|No| Return400[Return 400 Bad Request]
ValidateInput -->|Yes| CreateGDriveFolder[Create Folder in Google Drive]
CreateGDriveFolder --> SaveToDB[Save Folder to MongoDB]
SaveToDB --> EmitUpdate[Emit Socket.IO folder:updated]
EmitUpdate --> ReturnFolder[Return Folder Data]
UpdateFolder --> AuthCheck{Admin - Auth?}
AuthCheck -->|No| Return403[Return 403 Forbidden]
AuthCheck -->|Yes| UpdateDB[Update MongoDB Record]
UpdateDB --> UpdateGDrive[Update Google Drive Metadata]
UpdateGDrive --> EmitUpdate
DeleteFolder --> AuthCheck
AuthCheck -->|Yes| CheckPDFs{Has - PDFs?}
CheckPDFs -->|Yes| Return400Delete[Return 400 Cannot Delete]
CheckPDFs -->|No| DeleteFromDB[Delete from MongoDB]
DeleteFromDB --> DeleteFromGDrive[Delete from Google Drive]
DeleteFromGDrive --> EmitUpdate
SyncGDrive --> AuthCheck
AuthCheck -->|Yes| FetchGDriveFolders[Fetch All Folders from Google Drive]
FetchGDriveFolders --> BuildHierarchy[Build Folder Hierarchy]
BuildHierarchy --> CompareDB[Compare with MongoDB]
CompareDB --> SyncChanges[Sync New/Updated Folders]
SyncChanges --> ReturnHierarchy[Return Folder Tree]
flowchart TD
Start([User Searches Folders]) --> SearchRequest[GET /api/folders/search?q=query]
SearchRequest --> AuthCheck{Authenticated?}
AuthCheck -->|No| Return401[Return 401 Unauthorized]
AuthCheck -->|Yes| ParseQuery[Parse Search Query]
ParseQuery --> BuildSearchCriteria[Build MongoDB Search Criteria - name, description, department]
BuildSearchCriteria --> ApplyAccessControl{User has - Access Tags?}
ApplyAccessControl -->|Yes| FilterByTags[Filter by Access Tags]
ApplyAccessControl -->|No| FilterByDeptYear[Filter by Department & Year]
FilterByTags --> ExecuteSearch[Execute MongoDB Query]
FilterByDeptYear --> ExecuteSearch
ExecuteSearch --> PopulatePDFs[Populate PDF Count]
PopulatePDFs --> SortResults[Sort by Relevance]
SortResults --> ReturnResults[Return Search Results]
flowchart TD
Start([App Starts]) --> LoadApp[Load App.jsx]
LoadApp --> InitProviders[Initialize Providers - GoogleOAuthProvider, AuthProvider]
InitProviders --> InitRouter[Initialize React Router]
InitRouter --> CheckAuth[AuthContext checks localStorage]
CheckAuth --> TokenExists{Token - Exists?}
TokenExists -->|No| ShowLanding[Show Landing Page]
TokenExists -->|Yes| VerifyToken[Verify Token with Backend - GET /api/auth/me]
VerifyToken --> ValidToken{Valid - Token?}
ValidToken -->|No| ClearStorage[Clear localStorage]
ClearStorage --> ShowLanding
ValidToken -->|Yes| SetAuthState[Set isAuthenticated = true]
SetAuthState --> ShowDashboard[Show Dashboard]
ShowLanding --> UserAction{User - Action?}
UserAction -->|Login| ShowLoginPage[Show Login Page]
UserAction -->|Browse| BrowseLanding[Browse Landing Page]
ShowLoginPage --> LoginMethod{Login - Method?}
LoginMethod -->|Email/Password| EmailLogin[Email/Password Login]
LoginMethod -->|Google OAuth| GoogleOAuth[Google OAuth Login]
EmailLogin --> AuthSuccess{Auth - Success?}
GoogleOAuth --> AuthSuccess
AuthSuccess -->|No| ShowError[Show Error Message]
AuthSuccess -->|Yes| SaveToken[Save Token to localStorage]
SaveToken --> SetAuthState
flowchart TD
Start([Dashboard Loads]) --> InitDashboard[DashboardPage.jsx]
InitDashboard --> CheckRoute{Route - Params?}
CheckRoute -->|/dashboard| LoadAllFolders[Load All Folders]
CheckRoute -->|/dashboard/folder/:id| LoadSpecificFolder[Load Specific Folder]
LoadAllFolders --> FetchFolders[GET /api/folders]
LoadSpecificFolder --> FetchFolder[GET /api/folders/:id]
FetchFolders --> ApplyFilters[Apply Department/Year Filters]
FetchFolder --> FetchPDFs[GET /api/pdfs?folderId=xxx]
ApplyFilters --> DisplayFolderGrid[Display Folder Grid]
FetchPDFs --> DisplayPDFList[Display PDF List]
DisplayFolderGrid --> UserSelectsFolder[User Clicks Folder]
UserSelectsFolder --> NavigateToFolder[Navigate to /dashboard/folder/:id]
NavigateToFolder --> LoadSpecificFolder
DisplayPDFList --> UserSelectsPDF[User Clicks PDF]
UserSelectsPDF --> OpenPDFViewer[Open SecurePDFViewer Modal]
OpenPDFViewer --> LoadPDFStream[Load PDF Stream]
LoadPDFStream --> RenderPDF[Render PDF with react-pdf-viewer]
RenderPDF --> ApplySecurity[Apply Security - Disable download, print, context menu]
sequenceDiagram
participant Admin
participant Backend
participant SocketIO
participant Client1
participant Client2
Admin->>Backend: Update Folder/PDF/AccessTag
Backend->>Backend: Save to MongoDB
Backend->>SocketIO: Emit event (folder:updated)
SocketIO->>Client1: Broadcast folder:updated
SocketIO->>Client2: Broadcast folder:updated
Client1->>Client1: Update local state
Client2->>Client2: Update local state
Client1->>Client1: Re-render UI
Client2->>Client2: Re-render UI
flowchart TD
Start([Admin Logs In]) --> AdminLogin[POST /api/auth/admin-login]
AdminLogin --> ValidateCreds{Valid - Credentials?}
ValidateCreds -->|No| ReturnError[Return 401 Error]
ValidateCreds -->|Yes| GenerateToken[Generate Admin JWT - 24h expiry]
GenerateToken --> SaveToken[Save Token to localStorage]
SaveToken --> LoadDashboard[Load Admin Dashboard]
LoadDashboard --> ShowSidebar[Show Sidebar Navigation]
ShowSidebar --> NavOption{Navigation - Option?}
NavOption -->|Dashboard| ShowAnalytics[Show Analytics Page]
NavOption -->|PDFs| ShowPDFManagement[Show PDF Management]
NavOption -->|Folders| ShowFolderManagement[Show Folder Management]
NavOption -->|Users| ShowUserManagement[Show User Management]
NavOption -->|Access Tags| ShowAccessTags[Show Access Tags]
NavOption -->|Settings| ShowSettings[Show Settings]
NavOption -->|Docs| ShowDocs[Show Documentation]
ShowPDFManagement --> PDFActions{PDF - Action?}
PDFActions -->|Upload| UploadPDF[Upload New PDF]
PDFActions -->|Edit| EditPDF[Edit PDF Metadata]
PDFActions -->|Delete| DeletePDF[Delete PDF]
PDFActions -->|Bulk| BulkOperations[Bulk Operations]
ShowFolderManagement --> FolderActions{Folder - Action?}
FolderActions -->|Create| CreateFolder[Create New Folder]
FolderActions -->|Edit| EditFolder[Edit Folder]
FolderActions -->|Delete| DeleteFolder[Delete Folder]
FolderActions -->|Sync| SyncGDrive[Sync with Google Drive]
ShowUserManagement --> UserActions{User - Action?}
UserActions -->|View| ViewUsers[View All Users]
UserActions -->|Edit| EditUser[Edit User Details]
UserActions -->|Delete| DeleteUser[Delete User]
UserActions -->|Force Logout| ForceLogout[Force User Logout]
flowchart TD
Start([Admin Views Analytics]) --> LoadAnalytics[GET /api/admin/analytics]
LoadAnalytics --> AuthCheck{Admin - Auth?}
AuthCheck -->|No| Return403[Return 403 Forbidden]
AuthCheck -->|Yes| AggregateData[Aggregate Data from AccessLog]
AggregateData --> CalculateMetrics[Calculate Metrics]
CalculateMetrics --> TotalUsers[Total Users Count]
CalculateMetrics --> TotalPDFs[Total PDFs Count]
CalculateMetrics --> TotalViews[Total PDF Views]
CalculateMetrics --> ActiveUsers[Active Users Today/Week/Month]
CalculateMetrics --> PopularPDFs[Most Viewed PDFs]
CalculateMetrics --> DepartmentStats[Department-wise Statistics]
TotalUsers --> ReturnAnalytics[Return Analytics Data]
TotalPDFs --> ReturnAnalytics
TotalViews --> ReturnAnalytics
ActiveUsers --> ReturnAnalytics
PopularPDFs --> ReturnAnalytics
DepartmentStats --> ReturnAnalytics
ReturnAnalytics --> RenderCharts[Render Charts & Graphs]
RenderCharts --> DisplayDashboard[Display Analytics Dashboard]
Start --> LoadLogs[GET /api/admin/logs]
LoadLogs --> AuthCheck
AuthCheck -->|Yes| QueryAccessLog[Query AccessLog Collection]
QueryAccessLog --> ApplyFilters[Apply Filters - date, action, user]
ApplyFilters --> SortByTime[Sort by Timestamp DESC]
SortByTime --> Paginate[Paginate Results]
Paginate --> ReturnLogs[Return Access Logs]
ReturnLogs --> DisplayTable[Display Logs Table]
flowchart TD
Start([Access Tag System]) --> CreateTag[Admin Creates Access Tag]
CreateTag --> SaveTag[POST /api/access-tags]
SaveTag --> StoreInDB[Store in MongoDB]
StoreInDB --> AssignToUser[Admin Assigns Tag to User]
AssignToUser --> UpdateUser[PUT /api/users/:id - Add accessTags array]
StoreInDB --> AssignToResource[Admin Assigns Tag to PDF/Folder]
AssignToResource --> UpdateResource[PUT /api/pdfs/:id or /api/folders/:id - Add accessTags array]
UpdateUser --> UserAccessCheck[User Requests Resource]
UpdateResource --> UserAccessCheck
UserAccessCheck --> CheckTags{Resource has - Access Tags?}
CheckTags -->|No| CheckDeptYear{Matches - Dept/Year?}
CheckTags -->|Yes| UserHasTags{User has - Required Tags?}
UserHasTags -->|No| DenyAccess[Deny Access - 403]
UserHasTags -->|Yes| GrantAccess[Grant Access]
CheckDeptYear -->|No| DenyAccess
CheckDeptYear -->|Yes| GrantAccess
flowchart TD
Start([PDF Security]) --> ClientSide[Client-Side Security]
Start --> ServerSide[Server-Side Security]
ClientSide --> DisableContextMenu[Disable Right-Click Context Menu]
ClientSide --> DisableDevTools[Disable F12 Dev Tools]
ClientSide --> DisableKeyboard[Disable Ctrl+S, Ctrl+P shortcuts]
ClientSide --> DisableSelection[Disable Text Selection]
ClientSide --> WatermarkOverlay[Add Watermark Overlay]
ClientSide --> ScreenshotProtection[Screenshot Protection Android]
ServerSide --> SignedURLs[Generate Signed URLs with TTL]
ServerSide --> ProxyStreaming[Proxy PDF Streaming through Backend]
ServerSide --> AccessLogging[Log All PDF Access]
ServerSide --> RateLimiting[Rate Limiting on PDF Endpoints]
ServerSide --> JWTValidation[JWT Token Validation]
SignedURLs --> ShortExpiry[Short Expiry Time 1-2 hours]
ProxyStreaming --> NoDirectAccess[No Direct Google Drive Access]
AccessLogging --> AuditTrail[Maintain Audit Trail]
flowchart TD
Start([Google Drive Service]) --> InitService[Initialize Google Drive Service]
InitService --> LoadCredentials[Load Service Account Credentials - from GDRIVE_CREDENTIALS env]
LoadCredentials --> Authenticate[Authenticate with Google Drive API]
Authenticate --> Operations{Operation - Type?}
Operations -->|Upload| UploadFile[Upload File to Drive]
Operations -->|List| ListFiles[List Files in Folder]
Operations -->|Get| GetFileMetadata[Get File Metadata]
Operations -->|Delete| DeleteFile[Delete File]
Operations -->|Create Folder| CreateFolder[Create Folder]
Operations -->|Set Permissions| SetPermissions[Set File Permissions]
UploadFile --> SetMetadata[Set File Metadata - name, mimeType, parents]
SetMetadata --> UploadContent[Upload File Content]
UploadContent --> SetPublicPermission[Set Public Read Permission]
SetPublicPermission --> ReturnFileId[Return File ID & Web Link]
ListFiles --> SpecifyFolder[Specify Parent Folder ID]
SpecifyFolder --> QueryFiles[Query Files API]
QueryFiles --> FilterResults[Filter by mimeType, trashed]
FilterResults --> ReturnFileList[Return File List]
GetFileMetadata --> RequestMetadata[Request File Metadata]
RequestMetadata --> ReturnMetadata[Return name, size, mimeType, etc.]
DeleteFile --> MoveToTrash[Move File to Trash]
MoveToTrash --> ReturnSuccess[Return Success]
CreateFolder --> SetFolderMetadata[Set Folder Metadata]
SetFolderMetadata --> CreateInDrive[Create in Google Drive]
CreateInDrive --> ReturnFolderId[Return Folder ID]
SetPermissions --> DefinePermission[Define Permission - type: anyone, role: reader]
DefinePermission --> ApplyPermission[Apply to File]
ApplyPermission --> ReturnSuccess
flowchart TD
Start([Multiple Base Folders]) --> LoadConfig[Load GDRIVE_BASE_FOLDER_ID env]
LoadConfig --> ParseConfig{Config - Format?}
ParseConfig -->|Single ID| SingleFolder[Use Single Base Folder]
ParseConfig -->|Comma-separated| MultipleCSV[Parse CSV into Array]
ParseConfig -->|Multiple Env Vars| MultipleEnv[Load GDRIVE_BASE_FOLDER_ID_2, _3, etc.]
SingleFolder --> StoreFolders[Store in baseFolderIds array]
MultipleCSV --> StoreFolders
MultipleEnv --> StoreFolders
StoreFolders --> SyncOperation[Sync Folders Operation]
SyncOperation --> IterateFolders[Iterate through Base Folder IDs]
IterateFolders --> FetchEachFolder[Fetch Folders from Each Base]
FetchEachFolder --> MergeResults[Merge All Results]
MergeResults --> ReturnCombined[Return Combined Folder Tree]
flowchart TD
Start([User Approval Check]) --> LoadSheetConfig[Load Google Sheets Config - APPROVED_USERS_SHEET_URL, GID]
LoadSheetConfig --> ParseSheetURL[Parse Sheet URL & GID]
ParseSheetURL --> FetchSheetData[Fetch Sheet Data via Google Sheets API]
FetchSheetData --> ParseRows[Parse Rows - Email, Name, Department, Year, Semester]
ParseRows --> CacheData[Cache Data in Memory - TTL: 5 minutes]
CacheData --> UserLogin[User Attempts Google OAuth Login]
UserLogin --> ExtractEmail[Extract Email from Google Payload]
ExtractEmail --> CheckCache{Email in - Cache?}
CheckCache -->|No| RefreshCache[Refresh Cache from Sheets]
RefreshCache --> CheckCache
CheckCache -->|Yes| UserApproved{User - Approved?}
UserApproved -->|No| DenyAccess[Deny Access - Not Approved]
UserApproved -->|Yes| ReturnUserData[Return User Data - name, department, year, semester]
ReturnUserData --> ProceedLogin[Proceed with Login]
sequenceDiagram
participant AdminClient
participant SocketIOServer
participant WebClient1
participant WebClient2
participant AndroidClient
AdminClient->>SocketIOServer: Connect
WebClient1->>SocketIOServer: Connect
WebClient2->>SocketIOServer: Connect
AndroidClient->>SocketIOServer: Connect
Note over SocketIOServer: All clients connected
AdminClient->>SocketIOServer: admin:folder:update {folderId, data}
SocketIOServer->>WebClient1: folder:updated {folderId, data}
SocketIOServer->>WebClient2: folder:updated {folderId, data}
SocketIOServer->>AndroidClient: folder:updated {folderId, data}
AdminClient->>SocketIOServer: admin:pdf:update {pdfId, data}
SocketIOServer->>WebClient1: pdf:updated {pdfId, data}
SocketIOServer->>WebClient2: pdf:updated {pdfId, data}
SocketIOServer->>AndroidClient: pdf:updated {pdfId, data}
AdminClient->>SocketIOServer: admin:accessTag:update {tagId, data}
SocketIOServer->>WebClient1: accessTag:updated {tagId, data}
SocketIOServer->>WebClient2: accessTag:updated {tagId, data}
SocketIOServer->>AndroidClient: accessTag:updated {tagId, data}
WebClient1->>SocketIOServer: Disconnect
Note over SocketIOServer: Client1 disconnected
flowchart TD
Start([Socket.IO Server]) --> ClientConnect[Client Connects]
ClientConnect --> LogConnection[Log Connection with socket.id]
LogConnection --> ListenEvents[Listen for Events]
ListenEvents --> FolderUpdate[admin:folder:update]
ListenEvents --> PDFUpdate[admin:pdf:update]
ListenEvents --> TagUpdate[admin:accessTag:update]
ListenEvents --> Disconnect[disconnect]
FolderUpdate --> LogFolderUpdate[Log Folder Update]
LogFolderUpdate --> BroadcastFolder[Broadcast folder:updated to all except sender]
PDFUpdate --> LogPDFUpdate[Log PDF Update]
LogPDFUpdate --> BroadcastPDF[Broadcast pdf:updated to all except sender]
TagUpdate --> LogTagUpdate[Log Access Tag Update]
LogTagUpdate --> BroadcastTag[Broadcast accessTag:updated to all except sender]
Disconnect --> LogDisconnect[Log Disconnection]
flowchart TD
Start([Android App]) --> InitCapacitor[Initialize Capacitor]
InitCapacitor --> LoadWebView[Load React App in WebView]
LoadWebView --> ConfigurePlugins[Configure Capacitor Plugins]
ConfigurePlugins --> ScreenProtection[Screenshot Protection Plugin]
ConfigurePlugins --> DeepLinking[Deep Linking edudrive://]
ConfigurePlugins --> PushNotifications[Push Notifications]
ConfigurePlugins --> FileSystem[File System Access]
ScreenProtection --> DisableScreenshots[Disable Screenshots & Screen Recording]
DeepLinking --> HandleOAuth[Handle OAuth Redirect - edudrive://app-login-success]
HandleOAuth --> ExtractToken[Extract Token from URL]
ExtractToken --> SaveToStorage[Save to Capacitor Storage]
SaveToStorage --> NavigateToDashboard[Navigate to Dashboard]
PushNotifications --> RegisterDevice[Register Device for Notifications]
RegisterDevice --> ReceiveNotifications[Receive Update Notifications]
FileSystem --> OfflineStorage[Store PDFs for Offline Viewing]
sequenceDiagram
participant AndroidApp
participant SystemBrowser
participant Backend
participant Google
AndroidApp->>SystemBrowser: Open /api/auth/google?platform=android
SystemBrowser->>Backend: GET /api/auth/google?platform=android
Backend->>SystemBrowser: Redirect to Google OAuth
SystemBrowser->>Google: User authorizes
Google->>Backend: Callback with code
Backend->>Backend: Verify & create user
Backend->>SystemBrowser: Redirect to edudrive://app-login-success?token=xxx
SystemBrowser->>AndroidApp: Deep link triggers app
AndroidApp->>AndroidApp: Extract token from URL
AndroidApp->>AndroidApp: Save token & navigate to dashboard
flowchart TD
Start([Error Occurs]) --> ErrorType{Error - Type?}
ErrorType -->|Validation Error| Return400[Return 400 Bad Request - with validation details]
ErrorType -->|Authentication Error| Return401[Return 401 Unauthorized]
ErrorType -->|Authorization Error| Return403[Return 403 Forbidden]
ErrorType -->|Not Found Error| Return404[Return 404 Not Found]
ErrorType -->|Conflict Error| Return409[Return 409 Conflict]
ErrorType -->|Rate Limit Error| Return429[Return 429 Too Many Requests]
ErrorType -->|Server Error| Return500[Return 500 Internal Server Error]
Return400 --> LogError[Log Error to Console]
Return401 --> LogError
Return403 --> LogError
Return404 --> LogError
Return409 --> LogError
Return429 --> LogError
Return500 --> LogError
LogError --> SetCORSHeaders[Ensure CORS Headers Set]
SetCORSHeaders --> ReturnJSON[Return JSON Error Response]
ReturnJSON --> ProductionCheck{Production - Mode?}
ProductionCheck -->|Yes| HideStack[Hide Stack Trace]
ProductionCheck -->|No| ShowStack[Include Stack Trace]
HideStack --> SendResponse[Send Response to Client]
ShowStack --> SendResponse
flowchart TD
Start([User Action]) --> LoggableAction{Loggable - Action?}
LoggableAction -->|Yes| CreateLogEntry[Create AccessLog Entry]
LoggableAction -->|No| SkipLogging[Skip Logging]
CreateLogEntry --> CaptureData[Capture Data]
CaptureData --> UserId[User ID]
CaptureData --> Action[Action Type - login, logout, view_pdf, etc.]
CaptureData --> PDFId[PDF ID if applicable]
CaptureData --> IPAddress[IP Address]
CaptureData --> UserAgent[User Agent]
CaptureData --> DeviceId[Device ID]
CaptureData --> Metadata[Additional Metadata]
CaptureData --> Timestamp[Timestamp]
UserId --> SaveToDB[Save to AccessLog Collection]
Action --> SaveToDB
PDFId --> SaveToDB
IPAddress --> SaveToDB
UserAgent --> SaveToDB
DeviceId --> SaveToDB
Metadata --> SaveToDB
Timestamp --> SaveToDB
SaveToDB --> IndexForQuery[Index for Fast Queries]
IndexForQuery --> AvailableForAnalytics[Available for Analytics]
graph TB
subgraph "Frontend Deployment - Vercel"
ClientBuild[Client Build - pnpm build]
AdminBuild[Admin Build - pnpm build]
ClientVercel[Deploy to Vercel - edudrive-client.vercel.app]
AdminVercel[Deploy to Vercel - edudrive-admin.vercel.app]
ClientBuild --> ClientVercel
AdminBuild --> AdminVercel
end
subgraph "Backend Deployment - Render/Vercel"
BackendDeploy[Backend Deployment]
SetEnvVars[Set Environment Variables]
BackendDeploy --> SetEnvVars
end
subgraph "Database - MongoDB Atlas"
MongoDBAtlas[(MongoDB Atlas - Cloud Database)]
end
subgraph "External Services"
GoogleServices[Google Cloud Services - OAuth, Drive, Sheets]
end
ClientVercel --> BackendDeploy
AdminVercel --> BackendDeploy
BackendDeploy --> MongoDBAtlas
BackendDeploy --> GoogleServices
subgraph "Android Deployment"
AndroidBuild[Build Android APK - pnpm build:android]
PlayStore[Google Play Store]
AndroidBuild --> PlayStore
end
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| POST | /api/auth/register |
Register new user | No |
| POST | /api/auth/login |
Email/password login | No |
| GET | /api/auth/google |
Initiate Google OAuth | No |
| GET | /api/auth/google/callback |
Google OAuth callback | No |
| POST | /api/auth/google-verify |
Verify Google credential token | No |
| POST | /api/auth/admin-login |
Admin login with env credentials | No |
| POST | /api/auth/logout |
Logout user | Yes |
| POST | /api/auth/admin-logout |
Logout admin | Yes |
| GET | /api/auth/me |
Get current user info | Yes |
| GET | /api/auth/admin/me |
Get current admin info | Yes (Admin) |
| POST | /api/auth/force-logout/:userId |
Force logout user | Yes (Admin) |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /api/pdfs |
List PDFs with filters | Yes |
| POST | /api/pdfs/upload |
Upload new PDF | Yes (Admin) |
| GET | /api/pdfs/:id |
Get PDF details | Yes |
| GET | /api/pdfs/:id/stream |
Stream PDF content | Yes |
| PUT | /api/pdfs/:id |
Update PDF metadata | Yes (Admin) |
| DELETE | /api/pdfs/:id |
Delete PDF | Yes (Admin) |
| POST | /api/pdfs/bulk-delete |
Bulk delete PDFs | Yes (Admin) |
| POST | /api/pdfs/bulk-update |
Bulk update PDFs | Yes (Admin) |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /api/folders |
List all folders | Yes |
| GET | /api/folders/search |
Search folders | Yes |
| GET | /api/folders/gdrive |
Sync with Google Drive | Yes (Admin) |
| GET | /api/folders/:id |
Get folder details | Yes |
| POST | /api/folders |
Create new folder | Yes (Admin) |
| PUT | /api/folders/:id |
Update folder | Yes (Admin) |
| DELETE | /api/folders/:id |
Delete folder | Yes (Admin) |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /api/users |
List all users | Yes (Admin) |
| GET | /api/users/:id |
Get user details | Yes (Admin) |
| PUT | /api/users/:id |
Update user | Yes (Admin) |
| DELETE | /api/users/:id |
Delete user | Yes (Admin) |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /api/admin/analytics |
Get analytics data | Yes (Admin) |
| GET | /api/admin/logs |
Get access logs | Yes (Admin) |
| GET | /api/admin/stats |
Get system statistics | Yes (Admin) |
| Method | Endpoint | Description | Auth Required |
|---|---|---|---|
| GET | /api/access-tags |
List all access tags | Yes (Admin) |
| POST | /api/access-tags |
Create access tag | Yes (Admin) |
| PUT | /api/access-tags/:id |
Update access tag | Yes (Admin) |
| DELETE | /api/access-tags/:id |
Delete access tag | Yes (Admin) |
flowchart TD
Start([User Opens App]) --> Landing[Landing Page]
Landing --> ClickLogin[Click Login]
ClickLogin --> ChooseMethod{Choose Login Method}
ChooseMethod -->|Google| GoogleOAuth[Google OAuth Flow]
ChooseMethod -->|Email| EmailLogin[Email/Password Login]
GoogleOAuth --> CheckApproval[Check Google Sheets Approval]
CheckApproval --> Approved{Approved?}
Approved -->|No| ShowError[Show Access Denied]
Approved -->|Yes| CreateUser[Create/Update User in DB]
EmailLogin --> ValidateCredentials[Validate Credentials]
ValidateCredentials --> Valid{Valid?}
Valid -->|No| ShowError
Valid -->|Yes| CreateUser
CreateUser --> GenerateJWT[Generate JWT Token]
GenerateJWT --> SaveToken[Save to localStorage]
SaveToken --> RedirectDashboard[Redirect to Dashboard]
RedirectDashboard --> LoadFolders[Load Folders from API]
LoadFolders --> ApplyFilters[Apply Department/Year Filters]
ApplyFilters --> DisplayFolders[Display Folder Grid]
DisplayFolders --> SelectFolder[User Selects Folder]
SelectFolder --> LoadPDFs[Load PDFs in Folder]
LoadPDFs --> DisplayPDFList[Display PDF List]
DisplayPDFList --> SelectPDF[User Selects PDF]
SelectPDF --> CheckPDFAccess{Has Access?}
CheckPDFAccess -->|No| ShowAccessDenied[Show Access Denied]
CheckPDFAccess -->|Yes| StreamPDF[Stream PDF from Backend]
StreamPDF --> RenderSecure[Render in Secure Viewer]
RenderSecure --> LogAccess[Log PDF Access]
LogAccess --> UserReads[User Reads PDF]
UserReads --> ClosePDF[Close PDF]
ClosePDF --> BackToDashboard[Back to Dashboard]
BackToDashboard --> DisplayFolders
graph LR
subgraph "Client & Admin"
React[React 19.1.0]
Vite[Vite 7.0.0]
TailwindCSS[Tailwind CSS]
ReactRouter[React Router]
Axios[Axios HTTP Client]
PDFViewer[react-pdf-viewer]
GoogleOAuth[Google OAuth Library]
SocketIOClient[Socket.IO Client]
ReactHotToast[React Hot Toast]
end
React --> Vite
React --> TailwindCSS
React --> ReactRouter
React --> Axios
React --> PDFViewer
React --> GoogleOAuth
React --> SocketIOClient
React --> ReactHotToast
graph LR
subgraph "Backend Stack"
NodeJS[Node.js v22+]
Express[Express.js]
MongoDB[MongoDB + Mongoose]
JWT[JSON Web Tokens]
GoogleAPIs[Google APIs - OAuth, Drive, Sheets]
SocketIO[Socket.IO]
Helmet[Helmet.js Security]
Morgan[Morgan Logging]
Compression[Compression]
RateLimit[Express Rate Limit]
end
NodeJS --> Express
Express --> MongoDB
Express --> JWT
Express --> GoogleAPIs
Express --> SocketIO
Express --> Helmet
Express --> Morgan
Express --> Compression
Express --> RateLimit
flowchart TD
subgraph "Client-Side Security"
DisableRightClick[Disable Right-Click]
DisableDevTools[Disable Dev Tools]
DisableKeyShortcuts[Disable Keyboard Shortcuts]
DisableTextSelection[Disable Text Selection]
Watermark[Watermark Overlay]
ScreenshotBlock[Screenshot Protection Android]
end
subgraph "Network Security"
HTTPS[HTTPS Only in Production]
CORS[CORS Configuration]
CSP[Content Security Policy]
RateLimiting[Rate Limiting]
end
subgraph "Authentication Security"
JWTTokens[JWT Tokens with Expiry]
PasswordHashing[Bcrypt Password Hashing]
DeviceTracking[Device ID Tracking]
AccountLocking[Account Locking after Failed Attempts]
end
subgraph "Authorization Security"
RBAC[Role-Based Access Control]
AccessTags[Access Tag System]
DeptYearFiltering[Department/Year Filtering]
end
subgraph "Data Security"
SignedURLs[Signed URLs with TTL]
ProxyStreaming[PDF Proxy Streaming]
NoDirectDownload[No Direct Download]
AccessLogging[Comprehensive Access Logging]
end
subgraph "Infrastructure Security"
HelmetJS[Helmet.js Headers]
InputValidation[Express Validator]
MongoDBInjection[MongoDB Injection Prevention]
EnvironmentVars[Environment Variable Protection]
end
This comprehensive flowchart covers:
- System Architecture: Overall structure with client, admin, backend, and external services
- Backend Architecture: Server initialization, database models, and route structure
- Authentication Flow: Multiple login methods including Google OAuth
- PDF Management: Upload, viewing, and streaming flows
- Folder Management: Hierarchy, Google Drive sync, and search
- Client Application: Initialization, dashboard, and real-time updates
- Admin Application: Dashboard, analytics, and management features
- Access Control: Tag system and security measures
- Google Drive Integration: Service architecture and multiple folder support
- Google Sheets Integration: User approval system
- Socket.IO: Real-time communication
- Android Integration: Capacitor bridge and OAuth flow
- Error Handling: Global error handler and logging
- Deployment: Production architecture
- API Endpoints: Complete endpoint reference
- Data Flow: Complete user journey
- Technology Stack: Frontend and backend technologies
- Security: Multi-layer security architecture
The EduDrive platform is a comprehensive, secure PDF management system with role-based access control, real-time updates, and multi-platform support (web and Android).