mirror of
https://github.com/bookorbit/bookorbit.git
synced 2026-11-03 08:21:39 -06:00
6769bf4b0f
The lockout was checked before the password was verified, so a correct password on a locked account returned the same generic invalid-credentials error as a wrong one. Users had no way to tell the two apart, and the natural response was to keep retrying a password that was already right. Completing a password reset did not clear the lock either, so the one recovery path the UI advertises appeared to fail for up to fifteen minutes after a successful reset. Verify the password first and report the lockout, with the remaining wait, only when the supplied password was correct. Someone guessing wrong passwords still gets the generic failure, so account existence is not leaked. Clear the lock whenever a password is reset or changed, and give admins an explicit unlock action for the case where waiting is not acceptable.
411 lines
12 KiB
JSON
411 lines
12 KiB
JSON
[
|
|
{
|
|
"file": "server/src/modules/user/user.controller.ts",
|
|
"className": "UserController",
|
|
"methodName": "setLibraries",
|
|
"httpMethod": "PUT",
|
|
"path": "/users/:id/libraries",
|
|
"permissions": ["Permission.ManageUsers"],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/user/user.controller.ts",
|
|
"className": "UserController",
|
|
"methodName": "adminResetPassword",
|
|
"httpMethod": "POST",
|
|
"path": "/users/:id/reset-password",
|
|
"permissions": ["Permission.ManageUsers"],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/user/user.controller.ts",
|
|
"className": "UserController",
|
|
"methodName": "unlockUser",
|
|
"httpMethod": "POST",
|
|
"path": "/users/:id/unlock",
|
|
"permissions": ["Permission.ManageUsers"],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/user-statistics/user-statistics.controller.ts",
|
|
"className": "UserStatisticsController",
|
|
"methodName": "getSummary",
|
|
"httpMethod": "GET",
|
|
"path": "/user-statistics/summary",
|
|
"permissions": [],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/user-statistics/user-statistics.controller.ts",
|
|
"className": "UserStatisticsController",
|
|
"methodName": "getDailyReading",
|
|
"httpMethod": "GET",
|
|
"path": "/user-statistics/daily-reading",
|
|
"permissions": [],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/user-statistics/user-statistics.controller.ts",
|
|
"className": "UserStatisticsController",
|
|
"methodName": "getReadingHeatmap",
|
|
"httpMethod": "GET",
|
|
"path": "/user-statistics/reading-heatmap",
|
|
"permissions": [],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/user-statistics/user-statistics.controller.ts",
|
|
"className": "UserStatisticsController",
|
|
"methodName": "getPeakHours",
|
|
"httpMethod": "GET",
|
|
"path": "/user-statistics/peak-hours",
|
|
"permissions": [],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/user-statistics/user-statistics.controller.ts",
|
|
"className": "UserStatisticsController",
|
|
"methodName": "getFavoriteDays",
|
|
"httpMethod": "GET",
|
|
"path": "/user-statistics/favorite-days",
|
|
"permissions": [],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/user-statistics/user-statistics.controller.ts",
|
|
"className": "UserStatisticsController",
|
|
"methodName": "getSessionTimeline",
|
|
"httpMethod": "GET",
|
|
"path": "/user-statistics/session-timeline",
|
|
"permissions": [],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/user-statistics/user-statistics.controller.ts",
|
|
"className": "UserStatisticsController",
|
|
"methodName": "updateSessionTimelineSession",
|
|
"httpMethod": "PATCH",
|
|
"path": "/user-statistics/session-timeline/:sessionId",
|
|
"permissions": [],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/user-statistics/user-statistics.controller.ts",
|
|
"className": "UserStatisticsController",
|
|
"methodName": "getCompletionTimeline",
|
|
"httpMethod": "GET",
|
|
"path": "/user-statistics/completion-timeline",
|
|
"permissions": [],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/user-statistics/user-statistics.controller.ts",
|
|
"className": "UserStatisticsController",
|
|
"methodName": "getGoalTrajectory",
|
|
"httpMethod": "GET",
|
|
"path": "/user-statistics/goal-trajectory",
|
|
"permissions": [],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/user-statistics/user-statistics.controller.ts",
|
|
"className": "UserStatisticsController",
|
|
"methodName": "getProgressFunnel",
|
|
"httpMethod": "GET",
|
|
"path": "/user-statistics/progress-funnel",
|
|
"permissions": [],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/user-statistics/user-statistics.controller.ts",
|
|
"className": "UserStatisticsController",
|
|
"methodName": "getCompletionLatency",
|
|
"httpMethod": "GET",
|
|
"path": "/user-statistics/completion-latency",
|
|
"permissions": [],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/user-statistics/user-statistics.controller.ts",
|
|
"className": "UserStatisticsController",
|
|
"methodName": "getGenreReadingTime",
|
|
"httpMethod": "GET",
|
|
"path": "/user-statistics/genre-reading-time",
|
|
"permissions": [],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/user-statistics/user-statistics.controller.ts",
|
|
"className": "UserStatisticsController",
|
|
"methodName": "getReadingPace",
|
|
"httpMethod": "GET",
|
|
"path": "/user-statistics/reading-pace",
|
|
"permissions": [],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/user-statistics/user-statistics.controller.ts",
|
|
"className": "UserStatisticsController",
|
|
"methodName": "getReadingSurvival",
|
|
"httpMethod": "GET",
|
|
"path": "/user-statistics/reading-survival",
|
|
"permissions": [],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/user-statistics/user-statistics.controller.ts",
|
|
"className": "UserStatisticsController",
|
|
"methodName": "getCompletionRace",
|
|
"httpMethod": "GET",
|
|
"path": "/user-statistics/completion-race",
|
|
"permissions": [],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/user-statistics/user-statistics.controller.ts",
|
|
"className": "UserStatisticsController",
|
|
"methodName": "getSessionArchetypes",
|
|
"httpMethod": "GET",
|
|
"path": "/user-statistics/session-archetypes",
|
|
"permissions": [],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/user-statistics/user-statistics.controller.ts",
|
|
"className": "UserStatisticsController",
|
|
"methodName": "getAuthorGenreChord",
|
|
"httpMethod": "GET",
|
|
"path": "/user-statistics/author-genre-chord",
|
|
"permissions": [],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/koreader/koreader.controller.ts",
|
|
"className": "KoreaderController",
|
|
"methodName": "createCredentials",
|
|
"httpMethod": "POST",
|
|
"path": "/koreader/credentials",
|
|
"permissions": ["Permission.KoreaderSync"],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/koreader/koreader.controller.ts",
|
|
"className": "KoreaderController",
|
|
"methodName": "updateCredentials",
|
|
"httpMethod": "PATCH",
|
|
"path": "/koreader/credentials",
|
|
"permissions": ["Permission.KoreaderSync"],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/koreader/koreader.controller.ts",
|
|
"className": "KoreaderController",
|
|
"methodName": "deleteCredentials",
|
|
"httpMethod": "DELETE",
|
|
"path": "/koreader/credentials",
|
|
"permissions": ["Permission.KoreaderSync"],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/koreader/koreader.controller.ts",
|
|
"className": "KoreaderController",
|
|
"methodName": "getCredentials",
|
|
"httpMethod": "GET",
|
|
"path": "/koreader/credentials",
|
|
"permissions": ["Permission.KoreaderSync"],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/koreader/koreader.controller.ts",
|
|
"className": "KoreaderController",
|
|
"methodName": "getSyncStatus",
|
|
"httpMethod": "GET",
|
|
"path": "/koreader/sync-status",
|
|
"permissions": ["Permission.KoreaderSync"],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/koreader/koreader.controller.ts",
|
|
"className": "KoreaderController",
|
|
"methodName": "getDevices",
|
|
"httpMethod": "GET",
|
|
"path": "/koreader/devices",
|
|
"permissions": ["Permission.KoreaderSync"],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/koreader/koreader.controller.ts",
|
|
"className": "KoreaderController",
|
|
"methodName": "getBookProgress",
|
|
"httpMethod": "GET",
|
|
"path": "/koreader/books/:bookId/progress",
|
|
"permissions": ["Permission.KoreaderSync"],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/koreader/koreader.controller.ts",
|
|
"className": "KoreaderController",
|
|
"methodName": "testConnection",
|
|
"httpMethod": "POST",
|
|
"path": "/koreader/test-connection",
|
|
"permissions": ["Permission.KoreaderSync"],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/notification/notification.controller.ts",
|
|
"className": "NotificationController",
|
|
"methodName": "list",
|
|
"httpMethod": "GET",
|
|
"path": "/notifications",
|
|
"permissions": ["Permission.NotificationAccess", "Permission.DemoRestricted"],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/notification/notification.controller.ts",
|
|
"className": "NotificationController",
|
|
"methodName": "getUnreadCount",
|
|
"httpMethod": "GET",
|
|
"path": "/notifications/unread-count",
|
|
"permissions": ["Permission.NotificationAccess", "Permission.DemoRestricted"],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/notification/notification.controller.ts",
|
|
"className": "NotificationController",
|
|
"methodName": "markAllAsRead",
|
|
"httpMethod": "PATCH",
|
|
"path": "/notifications/read-all",
|
|
"permissions": ["Permission.NotificationAccess", "Permission.DemoRestricted"],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/notification/notification.controller.ts",
|
|
"className": "NotificationController",
|
|
"methodName": "markAsRead",
|
|
"httpMethod": "PATCH",
|
|
"path": "/notifications/:id/read",
|
|
"permissions": ["Permission.NotificationAccess", "Permission.DemoRestricted"],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/notification/notification.controller.ts",
|
|
"className": "NotificationController",
|
|
"methodName": "dismiss",
|
|
"httpMethod": "DELETE",
|
|
"path": "/notifications/:id",
|
|
"permissions": ["Permission.NotificationAccess", "Permission.DemoRestricted"],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
},
|
|
{
|
|
"file": "server/src/modules/notification/notification.controller.ts",
|
|
"className": "NotificationController",
|
|
"methodName": "clearAll",
|
|
"httpMethod": "DELETE",
|
|
"path": "/notifications",
|
|
"permissions": ["Permission.NotificationAccess", "Permission.DemoRestricted"],
|
|
"libraryAccess": [],
|
|
"isPublic": false,
|
|
"allowDefault": false,
|
|
"useGuards": []
|
|
}
|
|
]
|