Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Granular access #5686

Merged
merged 21 commits into from
Jun 20, 2024
Merged

Granular access #5686

merged 21 commits into from
Jun 20, 2024

Conversation

sogehige
Copy link
Collaborator

@sogehige sogehige commented Feb 26, 2024

CHECKLIST
  • I read contributing docs
  • Not hooked on socket but needs update
    • Timers
    • Permissions
    • Core/Stats
    • Registries/Alert
    • Randomizer

Summary by CodeRabbit

  • New Features

    • Introduced a new type Unpacked<T> for enhanced type extraction.
    • Added scope methods across various classes for refined permission and scope management.
    • Implemented decorators for HTTP endpoints (Post, Get, Delete) to streamline API request handling.
    • Enhanced settings management with support for sensitive settings and scope-based visibility.
  • Refactor

    • Generalized event handler signatures and updated method calls for consistency and flexibility.
    • Transitioned to a class-based approach in database entity definitions for better structure and TypeORM integration.
    • Refined permission handling with new properties and updated logic for permission scopes.
    • Consolidated endpoint and socket handling with new functions and middleware for improved scope and privilege management.
  • Bug Fixes

    • Fixed permission assignment logic to correctly utilize user's highest permission level.
    • Adjusted menu and widget configurations to correctly incorporate scope and permission considerations.
  • Chores

    • Database migrations added for updating permissions table with new scope-related columns.

src/_interface.ts Fixed Show fixed Hide fixed
src/permissions.ts Fixed Show fixed Hide fixed
src/systems/alias.ts Fixed Show fixed Hide fixed
src/systems/alias.ts Fixed Show fixed Hide fixed
src/systems/alias.ts Fixed Show fixed Hide fixed
src/helpers/socket.ts Dismissed Show dismissed Hide dismissed
src/permissions.ts Fixed Show fixed Hide fixed
src/permissions.ts Fixed Show fixed Hide fixed
src/permissions.ts Fixed Show fixed Hide fixed
src/_interface.ts Fixed Show fixed Hide fixed
src/integrations/_interface.ts Fixed Show fixed Hide fixed
src/overlays/_interface.ts Fixed Show fixed Hide fixed
src/widgets/_interface.ts Fixed Show fixed Hide fixed
src/systems/alias.ts Fixed Show fixed Hide fixed
src/systems/alias.ts Fixed Show fixed Hide fixed
src/systems/alias.ts Fixed Show fixed Hide fixed
src/systems/alias.ts Fixed Show fixed Hide fixed
src/systems/checklist.ts Fixed Show fixed Hide fixed
src/systems/checklist.ts Fixed Show fixed Hide fixed
src/systems/cooldown.ts Fixed Show fixed Hide fixed
src/systems/cooldown.ts Fixed Show fixed Hide fixed
src/systems/cooldown.ts Fixed Show fixed Hide fixed
src/systems/cooldown.ts Fixed Show fixed Hide fixed
src/decorators/endpoint.ts Fixed Show fixed Hide fixed
src/decorators/endpoint.ts Fixed Show fixed Hide fixed
src/decorators/endpoint.ts Fixed Show fixed Hide fixed
src/systems/checklist.ts Fixed Show fixed Hide fixed
src/systems/checklist.ts Fixed Show fixed Hide fixed
src/systems/cooldown.ts Fixed Show fixed Hide fixed
src/decorators/endpoint.ts Fixed Show fixed Hide fixed
src/decorators/endpoint.ts Fixed Show fixed Hide fixed
src/decorators/endpoint.ts Fixed Show fixed Hide fixed
src/_interface.ts Fixed Show fixed Hide fixed
src/_interface.ts Fixed Show fixed Hide fixed
Copy link

coderabbitai bot commented Mar 14, 2024

Important

Review skipped

More than 25% of the files skipped due to max files limit. The review is being skipped to prevent a low-quality review.

88 files out of 147 files are above the max files limit of 50. Please upgrade to Pro plan to get higher limits.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This update ushers in a wave of enhancements across the system, focusing on refining permissions management, bolstering API endpoint security, and enhancing system extensibility. Key highlights include the introduction of the Unpacked<T> type for improved type extraction, alongside the implementation of scope-based permissions and endpoint definitions. These changes streamline error handling, fortify settings management, and optimize socket communication, paving the way for a more resilient and adaptable framework for future developments.

Changes

Files Change Summary
d.ts/global.d.ts, d.ts/index.d.ts Added mocha property and Unpacked<T> type
d.ts/src/helpers/socket.d.ts Generalized stopwatch::update event handler signature
src/_interface.ts, src/helpers/socket.ts, src/permissions.ts, ... Enhanced permissions, endpoint security, and settings management. Introduced randomUUID import, scope handling, and error response improvements.
src/database/..., src/database/migration/*/*/1678892044040-permissionScopes.ts Database schema updates for permissions and migration scripts for permissions table changes.
src/decorators.ts, src/decorators/endpoint.ts, src/decorators/on.ts Added endpoint and event decorators, and modified settings function.
src/integrations/*, src/overlays/*, src/plugins.ts, src/registries/overlays.ts, src/socket.ts, src/ui.ts, src/widgets/* Refactored to use new endpoint function and adjusted for scope-based permissions.
src/systems/* Added API endpoint decorators and refactored for API request handling.

Poem

In the realm of code, where bits do play,
A rabbit toils, improving day by day.
🐾 Through data fields, it dances free,
🌟 Securing systems, for you and me.
With scopes and permissions, a tale so grand,
Crafting a world, with a gentle hand.
🚀 To the future, it leaps and flies,
🐇 CodeRabbit's work, reaching the skies.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

Share
Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai generate interesting stats about this repository and render them as a table.
    • @coderabbitai show all the console.log statements in this repository.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (invoked as PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Additionally, you can add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.

CodeRabbit Configration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review Status

Actionable comments generated: 26

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between dcb8b9c and 7f11c23.
Files selected for processing (78)
  • d.ts/global.d.ts (1 hunks)
  • d.ts/index.d.ts (1 hunks)
  • d.ts/src/helpers/socket.d.ts (1 hunks)
  • src/_interface.ts (12 hunks)
  • src/customvariables.ts (1 hunks)
  • src/dashboard.ts (1 hunks)
  • src/database/BotEntity.ts (3 hunks)
  • src/database/entity/alias.ts (2 hunks)
  • src/database/entity/checklist.ts (1 hunks)
  • src/database/entity/commands.ts (1 hunks)
  • src/database/entity/cooldown.ts (1 hunks)
  • src/database/entity/event.ts (1 hunks)
  • src/database/entity/howLongToBeatGame.ts (1 hunks)
  • src/database/entity/keyword.ts (1 hunks)
  • src/database/entity/permissions.ts (2 hunks)
  • src/database/entity/plugins.ts (1 hunks)
  • src/database/entity/price.ts (1 hunks)
  • src/database/entity/quotes.ts (1 hunks)
  • src/database/entity/randomizer.ts (1 hunks)
  • src/database/entity/rank.ts (1 hunks)
  • src/database/entity/song.ts (1 hunks)
  • src/database/entity/timer.ts (1 hunks)
  • src/database/migration/mysql/22.x/1678892044040-permissionScopes.ts (1 hunks)
  • src/database/migration/postgres/22.x/1678892044040-permissionScopes.ts (1 hunks)
  • src/database/migration/sqlite/22.x/1678892044040-permissionScopes.ts (1 hunks)
  • src/decorators.ts (5 hunks)
  • src/decorators/endpoint.ts (1 hunks)
  • src/decorators/on.ts (2 hunks)
  • src/emotes.ts (2 hunks)
  • src/events.ts (1 hunks)
  • src/games/gamble.ts (1 hunks)
  • src/general.ts (3 hunks)
  • src/helpers/customvariables/setValueOf.ts (1 hunks)
  • src/helpers/panel.ts (1 hunks)
  • src/helpers/permissions/getUserHighestPermission.ts (1 hunks)
  • src/helpers/socket.ts (3 hunks)
  • src/integrations/_interface.ts (1 hunks)
  • src/integrations/obswebsocket.ts (2 hunks)
  • src/integrations/tiltify.ts (2 hunks)
  • src/overlays/_interface.ts (1 hunks)
  • src/overlays/bets.ts (1 hunks)
  • src/overlays/clipscarousel.ts (1 hunks)
  • src/overlays/countdown.ts (2 hunks)
  • src/overlays/credits.ts (3 hunks)
  • src/overlays/eventlist.ts (2 hunks)
  • src/overlays/marathon.ts (2 hunks)
  • src/overlays/polls.ts (1 hunks)
  • src/overlays/stats.ts (1 hunks)
  • src/overlays/stopwatch.ts (3 hunks)
  • src/permissions.ts (8 hunks)
  • src/plugins.ts (2 hunks)
  • src/registries/overlays.ts (3 hunks)
  • src/socket.ts (7 hunks)
  • src/stats/_interface.ts (1 hunks)
  • src/systems/alias.ts (3 hunks)
  • src/systems/checklist.ts (1 hunks)
  • src/systems/commercial.ts (2 hunks)
  • src/systems/cooldown.ts (4 hunks)
  • src/systems/customcommands.ts (2 hunks)
  • src/systems/highlights.ts (2 hunks)
  • src/systems/howlongtobeat.ts (4 hunks)
  • src/systems/keywords.ts (1 hunks)
  • src/systems/levels.ts (5 hunks)
  • src/systems/moderation.ts (12 hunks)
  • src/systems/points.ts (4 hunks)
  • src/systems/price.ts (2 hunks)
  • src/systems/quotes.ts (1 hunks)
  • src/systems/raffles.ts (2 hunks)
  • src/systems/ranks.ts (1 hunks)
  • src/systems/songs.ts (7 hunks)
  • src/systems/timers.ts (1 hunks)
  • src/systems/userinfo.ts (1 hunks)
  • src/tts.ts (2 hunks)
  • src/ui.ts (2 hunks)
  • src/users.ts (1 hunks)
  • src/widgets/_interface.ts (1 hunks)
  • src/widgets/chat.ts (2 hunks)
  • src/widgets/custom.ts (1 hunks)
Check Runs (1)
CodeQL failure (11)
  • src/_interface.ts: 200-200: This use of variable 'type' always evaluates to true.
  • src/_interface.ts: 319-319: This route handler performs authorization, but is not rate-limited.
  • src/_interface.ts: 335-335: This route handler performs authorization, but is not rate-limited.
  • src/decorators/endpoint.ts: 36-36: This route handler performs authorization, but is not rate-limited.
  • src/decorators/endpoint.ts: 107-107: This route handler performs authorization, but is not rate-limited.
  • src/decorators/endpoint.ts: 163-163: This route handler performs authorization, but is not rate-limited.
  • src/helpers/socket.ts: 153-153: This condition guards a sensitive action, but a user-provided value controls it.
  • src/integrations/_interface.ts: 13-13: This use of variable 'type' always evaluates to true.
  • src/overlays/_interface.ts: 13-13: This use of variable 'type' always evaluates to true.
  • src/permissions.ts: 45-45: This route handler performs authorization, but is not rate-limited.
  • src/widgets/_interface.ts: 13-13: This use of variable 'type' always evaluates to true.
Additional comments: 122
d.ts/global.d.ts (1)
  • 2-5: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [1-5]

The addition of the mocha property to the NodeJS.Global interface seems appropriate for testing purposes. Ensure that its usage is confined to test environments to avoid unintended side effects in production.

src/database/entity/checklist.ts (1)
  • 1-12: Transitioning to a class-based approach with TypeORM decorators for the Checklist entity enhances modularity and maintainability. Ensure that the data types for id and isCompleted are appropriate for their usage within the application.
src/stats/_interface.ts (1)
  • 1-13: The implementation of the scope method in the Overlay class aligns with the objective of enhancing access control. Ensure that the scope string 'stats:read' is consistent with the application's access control policies.
src/helpers/permissions/getUserHighestPermission.ts (1)
  • 2-14: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [5-15]

The modification to return a Promise<Permissions> in getUserHighestPermission enhances the function's utility by providing detailed permission information. Ensure that all callers of this function are updated to handle the new return type.

src/overlays/clipscarousel.ts (1)
  • 1-11: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [3-14]

Renaming the publicEndpoint function to endpoint and adjusting its signature within the ClipsCarousel class likely aims to standardize endpoint definitions. Ensure that the implementation and all references to the old function name are correctly updated across the project.

src/database/entity/rank.ts (1)
  • 9-9: Renaming schema to _schema in the Rank class aligns with conventions for indicating non-public properties. Ensure all references to this property are updated throughout the project to avoid breaking changes.
Verification successful

The renaming of schema to _schema in the Rank class and its consistent application across the project has been verified. All references to this property have been correctly updated, and there are no unintended references to the old schema property. The mention of schema in src/helpers/logTypeorm.ts is unrelated to the property renaming and does not affect this conclusion.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify that all references to the `schema` property are updated to `_schema`.
rg --type ts '_schema' src/
# Additionally, check for any remaining references to the old `schema` property.
rg --type ts 'schema' src/ | grep -v '_schema'

Length of output: 1273

src/database/entity/quotes.ts (1)
  • 8-8: Renaming schema to _schema in the Quotes class is consistent with conventions for indicating non-public properties. Ensure all references to this property are updated throughout the project to avoid breaking changes.
Verification successful

The verification process confirms that the renaming of schema to _schema has been successfully applied across the project in relevant files. The remaining reference to schema found in src/helpers/logTypeorm.ts is unrelated to the property renaming and pertains to a different context, indicating no issues with the renaming process.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify that all references to the `schema` property are updated to `_schema`.
rg --type ts '_schema' src/
# Additionally, check for any remaining references to the old `schema` property.
rg --type ts 'schema' src/ | grep -v '_schema'

Length of output: 1273

src/dashboard.ts (1)
  • 8-8: Modifying the @settings() decorator call with additional parameters likely aims to refine settings management. Consider providing more context or documentation regarding these parameters to ensure clarity for future maintainers.
src/database/entity/cooldown.ts (1)
  • 8-8: Renaming schema to _schema in the Cooldown class is consistent with conventions for indicating non-public properties. Ensure all references to this property are updated throughout the project to avoid breaking changes.
Verification successful

The verification process confirms that the renaming from schema to _schema has been successfully applied across the project, with all references updated accordingly. The remaining reference to schema found is unrelated to the entity properties, indicating no issues with the renaming effort.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify that all references to the `schema` property are updated to `_schema`.
rg --type ts '_schema' src/
# Additionally, check for any remaining references to the old `schema` property.
rg --type ts 'schema' src/ | grep -v '_schema'

Length of output: 1273

src/widgets/custom.ts (1)
  • 2-4: Reordering import statements for WidgetCustom and AppDataSource is a minor change. Ensure that this reordering does not impact the initialization or functionality of the imported entities.
Verification successful

The reordering of import statements for WidgetCustom and AppDataSource in src/widgets/custom.ts is consistent with the usage patterns observed throughout the application. This change does not seem to impact the initialization or functionality of the imported entities.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify that the reordering of import statements does not impact initialization or functionality.
rg --type ts 'WidgetCustom|AppDataSource' src/

Length of output: 49876

src/database/entity/price.ts (1)
  • 9-9: Renaming schema to _schema aligns with conventions for indicating non-public properties. Ensure all internal references to this property are updated to reflect this change.
src/database/entity/plugins.ts (1)
  • 8-8: Renaming schema to _schema in the Plugin class is consistent with naming conventions. Verify that all internal references to this property are correctly updated.
src/systems/checklist.ts (3)
  • 7-7: The introduction of Get and Post decorators for API endpoints is a positive change, enhancing clarity and maintainability. Ensure that the corresponding routing and middleware logic has been updated to reflect these changes.
  • 14-22: Refactoring to findAll and saveOneGroup methods from a generic sockets method improves code readability and operation specificity. This is a commendable change that enhances the clarity of the codebase.
  • 15-21: Replacing AppDataSource with direct calls to ChecklistEntity simplifies database operations and aligns with ORM practices. Review any custom logic in AppDataSource to ensure it's not inadvertently bypassed.
src/database/entity/keyword.ts (1)
  • 8-8: Renaming schema to _schema in the Keyword class follows the project's naming conventions. Ensure all internal references to this property are correctly updated.
src/database/entity/alias.ts (2)
  • 10-10: Updating the schema definition in the Alias class improves code clarity. Thoroughly test to ensure that functionality remains intact and all references to updated properties are correctly handled.
  • 40-40: Updating the schema definition in the AliasGroup class enhances code clarity. Ensure thorough testing to verify that functionality remains unaffected and all references are correctly updated.
src/database/BotEntity.ts (2)
  • 6-6: Renaming schema to _schema in the BotEntity class aligns with naming conventions. Verify that validation logic is correctly implemented following the removal of the validate method and that all references to the _schema property are updated.
  • 33-34: Integrating validation into the save method using the _schema property is a positive change for data integrity. Perform performance testing and monitor for any unexpected behavior due to this integrated validation logic.
src/database/migration/sqlite/22.x/1678892044040-permissionScopes.ts (1)
  • 6-20: The migration script for permission scopes correctly introduces haveAllScopes and scopes columns. Ensure thorough testing, particularly on a backup of the production database, to prevent data loss and verify the migration's integrity.
src/database/entity/permissions.ts (1)
  • 37-41: Adding haveAllScopes and scopes properties to the Permissions class is crucial for the new granular access control system. Thoroughly test to ensure these properties are correctly utilized and the transition to the new permissions system is seamless.
src/database/entity/commands.ts (1)
  • 9-9: Renaming schema to _schema in the Commands class aligns with the convention of indicating private or protected properties. Ensure all references to this property are updated accordingly.
src/database/entity/timer.ts (1)
  • 9-9: Renaming schema to _schema in the Timer class is consistent with best practices for indicating non-public properties. Verify that all usages of this property have been updated to reflect the change.
src/database/entity/howLongToBeatGame.ts (1)
  • 10-10: Renaming schema to _schema in the HowLongToBeatGame class is consistent with the convention for indicating private or protected properties. Ensure all references to this property are updated accordingly.
src/database/entity/song.ts (1)
  • 21-21: Renaming schema to _schema in the SongPlaylist class aligns with best practices for indicating private or protected properties. Confirm that all usages of this property have been updated to reflect the change.
src/database/entity/randomizer.ts (1)
  • 11-11: Renaming schema to _schema in the Randomizer class is a good practice for indicating private or protected properties. Ensure all references to this property are updated accordingly.
src/systems/commercial.ts (1)
  • 5-13: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [1-59]

The removal of the sockets method from the Commercial class alters the control flow and logic. Ensure that all functionalities previously handled by this method are either no longer required or have been migrated to other parts of the system. Additionally, verify that this change aligns with the PR's objectives of enhancing access control and permissions.

src/helpers/panel.ts (1)
  • 22-22: The addition of scopeParent to the menu array type enhances the flexibility and control over UI elements. Ensure that this change is integrated properly with the UI rendering logic and access control mechanisms.
src/overlays/credits.ts (2)
  • 15-15: Replacing publicEndpoint with endpoint and updating method signatures likely aligns with changes in access control or endpoint categorization. Ensure that these changes are consistent with the intended access control strategy and that the additional parameters in method signatures are properly integrated and documented.
  • 31-37: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [34-54]

Ensure that the additional parameters in the endpoint method calls are correctly handled and documented, especially in the context of fetching and processing data.

src/ui.ts (2)
  • 14-14: The change from publicEndpoint to endpoint and adjustments in logic for handling sensitive scopes and settings retrieval, along with the response format change to json, align with improvements in endpoint management, security, and data handling. Ensure these changes are consistently integrated with the project's strategies and that the response format change is beneficial across all relevant endpoints.
  • 49-82: The adjustments in logic for handling sensitive scopes and settings retrieval, as well as the response format change to json, enhance security and data processing consistency. Verify that these changes are correctly implemented and documented, especially in the context of sensitive data handling.
src/registries/overlays.ts (2)
  • 10-10: Replacing publicEndpoint with endpoint and adjusting the corresponding function calls likely aligns with changes in access control or endpoint categorization. Ensure that these changes are consistent with the intended access control strategy and that the adjustments to endpoint paths and callback handling are properly integrated and documented.
  • 74-81: Ensure that the adjustments to endpoint paths and callback handling are correctly implemented and documented, especially in the context of enhancing functionality and data handling.
src/overlays/stopwatch.ts (2)
  • 6-6: Switching from publicEndpoint to endpoint and adjusting the usage of MINUTE and SECOND constants, along with the type assertion for statusUpdate data retrieval, align with refinements in endpoint management, timing accuracy, and type safety. Ensure these changes are consistently integrated with the project's strategies and that the type assertion is necessary and beneficial.
  • 50-56: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [53-71]

Ensure that the type assertion for statusUpdate data retrieval is correctly implemented and necessary for type safety or data handling. Verify that this change enhances the functionality and reliability of the stopwatch::update endpoint.

src/overlays/countdown.ts (2)
  • 8-8: Replacing publicEndpoint with endpoint and modifying the callback function signature within the countdown::update endpoint likely aligns with refinements in endpoint management and enhances flexibility in data handling. Ensure these changes are consistent with the intended access control strategy and that the modification of the callback function signature is properly integrated and documented.
  • 71-71: Ensure that the modification of the callback function signature to accept generic parameters is correctly implemented and enhances the functionality and flexibility of the countdown::update endpoint.
src/customvariables.ts (1)
  • 27-31: The addition of scopeParent to the addMenu method call and the restructuring of object properties enhance the flexibility and control over UI elements for custom variables. Ensure that this change is integrated properly with the UI rendering logic and access control mechanisms for custom variables.
src/helpers/customvariables/setValueOf.ts (1)
  • 55-56: The adjustment in logic for checking user permissions, including the comparison between highestPermission and variablePermission, enhances security by ensuring appropriate access control for modifying custom variables. Ensure that this change is correctly implemented, integrated with the permissions management strategy, and properly documented.
d.ts/index.d.ts (1)
  • 15-19: The introduction of the Unpacked<T> type is a valuable addition for extracting nested types from arrays, functions, and promises. This utility type enhances the type system's flexibility and expressiveness.
src/decorators/on.ts (2)
  • 17-17: The addition of the settingsSave event to the onEvents type and the on object is a logical extension of the event handling system, allowing for more granular control over settings changes.
  • 152-157: The onSettingsSave function correctly implements event handler registration for the settingsSave event, following the established pattern in the file. This addition enhances the system's ability to respond to settings changes.
src/overlays/eventlist.ts (2)
  • 12-12: The modification of the import statement to use endpoint instead of publicEndpoint aligns with the project's refactoring efforts towards a more consistent and flexible endpoint handling mechanism.
  • 53-53: The update to the function call to endpoint with an empty array as the first argument correctly reflects the new approach to endpoint definition and scope handling, making the endpoint's scope requirements more explicit.
src/widgets/chat.ts (2)
  • 15-15: The modification of the import statement to use endpoint instead of publicEndpoint is consistent with the project's efforts to standardize and clarify endpoint handling across the codebase.
  • 131-131: The update to the function call to endpoint with an empty array as the first argument is part of the project-wide refactoring effort, correctly reflecting the new approach to endpoint definition and scope handling.
src/integrations/obswebsocket.ts (2)
  • 21-21: The renaming of publicEndpoint to endpoint aligns with the project's refactoring goals, simplifying the naming convention and making the endpoint handling mechanism more consistent across the codebase.
  • 118-118: The adjustment to the endpoint function signature, adding an empty array parameter and specifying the type of the opts parameter as any, correctly reflects the new approach to endpoint definition and scope handling.
src/overlays/marathon.ts (2)
  • 9-9: The import statement correctly updates publicEndpoint to endpoint. This change aligns with the PR's objective to enhance access control and permissions.
  • 160-160: The update from publicEndpoint to endpoint with an empty array as the first argument before the route string is correctly implemented. This change likely enhances the flexibility and control over access to the endpoint, aligning with the PR's objectives for granular access control.
src/integrations/tiltify.ts (2)
  • 12-12: The import statement correctly updates publicEndpoint to endpoint. This change aligns with the PR's objective to enhance access control and permissions.
  • 181-181: The update from publicEndpoint to endpoint with an empty array as the first argument before the route string is correctly implemented. This change likely enhances the flexibility and control over access to the endpoint, aligning with the PR's objectives for granular access control.
src/games/gamble.ts (1)
  • 67-67: The modification to assign permId using getUserHighestPermission(opts.sender.userId).id is logical for implementing granular access control. However, ensure that getUserHighestPermission always returns an object with an id property to avoid potential runtime errors.
src/helpers/socket.ts (3)
  • 16-124: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [1-60]

The introduction of jwt and isEqual imports, along with the management of scopes and new functions like addScope, getPrivileges, and initEndpoints, significantly enhances the system's access control and permissions management. Ensure to thoroughly test the integration and functionality of this new permissions and scopes management system.

  • 62-120: The updates to initEndpoints and the introduction of the endpoint function for defining new endpoints with specific scopes are crucial for the new granular access control system. It's important to ensure these changes are thoroughly tested, especially the correct initialization of endpoints based on user privileges.
  • 138-181: Refactoring publicEndpoint into the more generic withScope middleware function is a significant improvement, offering a flexible and secure way to manage endpoint access based on scopes. Ensure that the withScope function is correctly integrated and thoroughly tested, particularly in handling both public and private scopes.
src/systems/price.ts (1)
  • 35-65: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [14-59]

The addition of Delete, Get, and Post decorators for defining API endpoints, along with the corresponding methods for handling PriceEntity instances, represents a significant architectural improvement. This approach enhances modularity, readability, and maintainability of the codebase. Ensure to thoroughly test these new endpoint definitions and their integration with the rest of the system.

src/systems/highlights.ts (1)
  • 40-88: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [11-83]

The introduction of Post, Get, and Delete decorators for defining API endpoints related to highlights, along with the trigger, findAll, removeOne methods, significantly enhances the system's functionality and architecture. These changes streamline the management of highlights and the process of checking video availability. Ensure to thoroughly test these new endpoint definitions and their integration with the highlights management system.

src/systems/quotes.ts (1)
  • 22-22: The addition of the scopeParent parameter with a value obtained from this.scope() in the addMenu method call is a good practice for ensuring correct scoping of UI elements. This change contributes to the system's modularity and maintainability.
src/tts.ts (1)
  • 52-55: The addition of the @onSettingsSave() decorator and refresh method is a good practice for re-initializing TTS services upon settings changes. This ensures that any updates to settings are promptly reflected in the TTS functionality.
src/socket.ts (2)
  • 20-20: Adding getPrivileges, initEndpoints, and scopes to the exported entities enhances the modularity and flexibility of the socket handling. This allows for more granular control over privileges and endpoint initialization based on user roles and permissions.
  • 81-81: The refactoring and updates in privilege handling and endpoint initialization logic, including the use of getPrivileges for generating privilege objects and the adjustments in initEndpoints based on these privileges, improve the security and flexibility of the authentication and authorization process. It's important to ensure that these changes are thoroughly tested, especially in scenarios with varying privilege levels and access scopes.

Also applies to: 115-115, 142-143, 165-165, 180-180, 215-219

src/database/entity/event.ts (1)
  • 158-158: Renaming schema to _schema in the Event class aligns with the convention of using underscores to denote private or protected properties. This change enhances the readability and maintainability of the code by clearly indicating the intended scope of the property.
src/permissions.ts (3)
  • 1-1: The addition of imports for scopes, withScope, and app is noted. Ensure these modules are used appropriately within the file and that their functionalities align with the intended enhancements to the permissions system.
  • 24-24: Adding scopeParent to the addMenu method enhances the scope management for permissions settings. This change aligns with the objective of improving granular access control.
  • 222-222: The introduction of scopes and haveAllScopes properties in permission creation is a significant enhancement. It allows for more granular access control, aligning with the PR's objectives. Ensure that these properties are utilized correctly in permission checks throughout the application.
src/systems/howlongtobeat.ts (3)
  • 12-12: The addition of Delete, Get, and Post decorators for defining HTTP endpoints is a positive architectural improvement. It enhances the clarity and maintainability of the code by clearly indicating the purpose and type of each endpoint.
  • 30-30: Including scopeParent in the addMenu method for the HowLongToBeat system aligns with the PR's goal of improving scope management. This change ensures that the system's menu items respect the defined scopes.
  • 79-133: Refactoring API endpoint implementations using decorators (@Get, @Post, @Delete) improves the readability and modularity of the code. Ensure that the logic within each endpoint is correctly handling requests and responses according to the application's requirements.
src/general.ts (2)
  • 11-11: The addition of the app import in general.ts is noted. Ensure that the app object is utilized appropriately for setting up API endpoints and handling requests within the file.
  • 82-82: Adding scopeParent to the addMenu method in the general.ts file is consistent with the PR's objectives of enhancing scope management. This ensures that the menu items for bot commands respect the defined scopes.
src/systems/ranks.ts (1)
  • 36-36: Including scopeParent in the addMenu method for the Ranks system aligns with the PR's goal of improving scope management. This ensures that the system's menu items respect the defined scopes.
src/plugins.ts (1)
  • 277-278: The update to the endpoint declaration with the inclusion of a scope parameter aligns well with the PR's objective of enhancing access control. Ensure that the implementation of the scope method effectively manages access rights as intended.
src/systems/userinfo.ts (1)
  • 301-301: The fix for the assignment of permId enhances the accuracy of permission checks, aligning with the PR's focus on access control. Consider adding a comment explaining the importance of this assignment for future maintainers.
src/systems/timers.ts (1)
  • 93-93: The addition of the scopeParent parameter to the addMenu method call enhances scope management within the menu system, aligning with the PR's objectives. Ensure that the implementation of the scope method effectively manages access control as intended.
src/decorators.ts (2)
  • 5-6: The addition of imports for MEDIUM and addScope from ./helpers/constants.js and ./helpers/socket.js respectively, indicates an enhancement in functionality related to permissions and scope management. Ensure that these imports are utilized effectively within the file and that their introduction does not introduce any circular dependencies or unused code.
  • 144-162: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [147-198]

The modifications in the settings function to include an isSecret parameter and handling for sensitive scope and secret settings are crucial for enhancing the security and flexibility of the settings management system. This change allows for the marking of certain settings as secret, which is essential for handling sensitive information securely. However, it's important to ensure that the implementation correctly handles these secret settings throughout the system, especially in terms of access control and data exposure.

  1. Ensure that the addition of the isSecret flag is consistently applied across all relevant parts of the system where settings are accessed or modified.
  2. Verify that the addScope function call with the sensitive scope is correctly implemented and that it integrates well with the overall permissions and scope management system.
  3. Consider adding documentation or comments explaining the purpose and usage of the isSecret parameter, to aid future developers in understanding and correctly utilizing this feature.
  • Verify the integration of the isSecret flag with the system's access control mechanisms.
  • Add documentation or comments for the isSecret parameter to improve code readability and maintainability.
src/systems/keywords.ts (2)
  • 16-16: The introduction of Delete, Get, and Post decorators from ~/decorators/endpoint.js aligns with the architectural improvements mentioned, enhancing the way HTTP endpoints are defined and handled.
  • 31-31: Adding scopeParent to the addMenu method is a good practice for scope management, ensuring that the keywords system respects the granular access control introduced in this PR.
src/systems/customcommands.ts (2)
  • 17-17: The addition of Post, Get, and Delete decorators from ~/decorators/endpoint.js is consistent with the architectural improvements aimed at enhancing the definition and handling of HTTP endpoints.
  • 46-46: Including scopeParent in the addMenu method is a positive change for scope management, ensuring that the custom commands system adheres to the granular access control improvements introduced in this PR.
src/systems/levels.ts (3)
  • 7-21: The reorganization of imports and addition of new constants (MINUTE, SECOND) improve the readability and maintainability of the code by grouping related imports together and using descriptive constants for time values.
  • 156-156: The retrieval of the user's highest permission using getUserHighestPermission and checking for its existence before proceeding is a good practice for ensuring that the user has the necessary permissions for the operation. This enhances the security and robustness of the permission handling logic.
  • 249-249: Similar to the previous comment, the use of getUserHighestPermission in the messageXP method for permission checks before processing XP for messages is a good security practice. It ensures that only users with valid permissions can have their XP processed, which is crucial for maintaining the integrity of the levels system.
src/emotes.ts (2)
  • 9-9: The modification of the import statement to use endpoint instead of publicEndpoint for socket handling is a significant change that could affect how emotes are managed and cached within the system. Ensure that this change aligns with the overall architecture and security model of the sogebot project, especially in terms of how emotes are exposed to different parts of the system and to external clients.
  • 73-73: The use of the endpoint function to handle the /core/emotes endpoint for getting the emotes cache is a good practice for organizing and managing API endpoints within the system. It simplifies the process of defining and handling requests, making the code more maintainable and easier to understand.
src/systems/alias.ts (3)
  • 13-13: The addition of Delete, Get, and Post decorators from '~/decorators/endpoint.js' aligns well with the PR's objectives to enhance access control and permissions through more granular and declarative endpoint definitions.
  • 58-76: The implementation of CRUD operations for AliasEntity and AliasGroup using Post, Get, and Delete decorators is well-done. It enhances the modularity and readability of the code by clearly defining the intended actions for each endpoint.
  • 13-13: The removal of the adminEndpoint import and the introduction of API endpoint decorators suggest a refactor of the sockets method to better accommodate the new, more declarative approach to defining API endpoints. This likely enhances the architecture and modularity of the code.
src/systems/raffles.ts (1)
  • 20-20: The addition of getLocalizedName from ~/helpers/getLocalizedName.js is a positive change, enhancing the file's functionality by enabling localization of names. This improves user experience by displaying localized names based on count, which is particularly useful in the context of raffles.
src/systems/cooldown.ts (3)
  • 18-18: The import of Delete, Get, and Post decorators from ~/decorators/endpoint.js introduces a more declarative way of defining API endpoints. This aligns with modern practices for building RESTful services and enhances readability and maintainability.
  • 79-97: The use of @Get, @Delete, and @Post decorators for defining API endpoints (findAll, findOne, removeOne, and saveOneGroup) significantly improves the clarity and conciseness of the code. This approach allows for easier identification and management of API routes, contributing to better maintainability and scalability of the codebase.
  • 100-103: The addition of a menu configuration in the constructor enhances the user interface by providing a structured way to navigate through commands related to cooldowns. This change improves the usability of the system for administrators or users with access to the menu, making it easier to manage cooldown settings.
src/users.ts (1)
  • 484-484: The modification to extract permId using (await getUserHighestPermission(userId)).id and subsequently using it to find the corresponding Permissions entity is a good practice. It ensures that the permission ID is correctly obtained and used, enhancing the accuracy and reliability of permission checks. This change contributes to better security and access control within the application.
src/systems/points.ts (4)
  • 20-20: The import of Post from ~/decorators/endpoint.js is correctly added to support the new @Post decorators introduced in this file. This aligns with the PR's objective of enhancing endpoint handling.
  • 157-157: The modification to getUserHighestPermission calls to access the id property directly is a logical change. However, ensure that the getUserHighestPermission method always returns an object with an id property to avoid potential runtime errors.
Verification successful

Given the lack of results from the initial script, it's clear that a different approach is needed to verify the method's behavior. Let's focus on finding the definition of getUserHighestPermission to inspect its return type directly. This will help us understand whether it always returns an object with an id property.


Given the challenges in locating the getUserHighestPermission method definition with the previous approaches, it's clear a broader search strategy is needed. Let's use rg (ripgrep) to search for the method name throughout the codebase. This should help us identify the method's definition and context, allowing us to better understand its return type and ensure it always includes an id property.


The search results have successfully located the definition of getUserHighestPermission within src/helpers/permissions/getUserHighestPermission.ts. The method signature indicates it returns a Promise<Permissions>, suggesting that the return type is indeed structured to include an id property, as the method's usage across various files consistently accesses this property.

Given this information, it can be inferred that the getUserHighestPermission method is designed to always return an object that includes an id property, aligning with the original review comment's concern for ensuring the method's return type includes this property to avoid runtime errors.

Based on the findings from the codebase:

  • The method getUserHighestPermission is defined to return a Promise<Permissions>, which is expected to include an id property.
  • The consistent usage of .id after calls to getUserHighestPermission across multiple files suggests that the expected return structure is well-understood and adhered to within the codebase.

Therefore, the review comment is verified as the method's implementation and usage align with the concern for ensuring the presence of an id property in its return type.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify that getUserHighestPermission always returns an object with an `id` property.
ast-grep --lang typescript --pattern $'getUserHighestPermission($_).id'

Length of output: 72



Script:

#!/bin/bash
# Find the definition of getUserHighestPermission to inspect its return type.
ast-grep --lang typescript --pattern $'function getUserHighestPermission($_) { $$$ }'

Length of output: 86



Script:

#!/bin/bash
# Use ripgrep to search for the getUserHighestPermission method in the codebase.
rg "getUserHighestPermission" -t ts

Length of output: 3404

* 250-255: The `postReset` method correctly implements logic to reset points and changelog. This method aligns with the PR's objectives of enhancing the points system's flexibility and control. Ensure that appropriate permissions checks are in place to prevent unauthorized access to this endpoint. * 257-257: The update to the `sockets` method to include new endpoint handlers is a logical extension of the system's functionality. Ensure that socket endpoints are secured and only accessible by authorized users, similar to HTTP endpoints.
Verification successful

The verification process has revealed that the adminEndpoint function is indeed used within the src/systems/points.ts file, specifically for a 'reset' endpoint. This suggests that there is a mechanism in place to restrict access to certain functionalities, likely to admin users, as indicated by the use of adminEndpoint. Additionally, the broader search across the project for security-related patterns (e.g., 'auth', 'secure', 'authorize', 'admin') has shown extensive use of these mechanisms across various files, indicating a consistent approach to securing endpoints and functionalities.

Given this context, it can be concluded that the update to the sockets method to include new endpoint handlers, as mentioned in the review comment, is indeed secured and likely only accessible by authorized users, following the project's pattern of using adminEndpoint and other security measures.

Therefore, the review comment is verified as accurate in the context of ensuring that socket endpoints are secured and only accessible by authorized users.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify that socket endpoints are secured and only accessible by authorized users.
ast-grep --lang typescript --pattern $'adminEndpoint("/systems/points", "reset", $$$)'

Length of output: 87



Script:

#!/bin/bash
# Search for broader security-related patterns in the src/systems/points.ts file
fd points.ts src/systems --exec rg -- 'auth|secure|authorize|admin' {}

# Additionally, search globally in the project for any security implementations that might be related to socket endpoints
rg -- 'auth|secure|authorize|admin' src/

Length of output: 39192

src/systems/moderation.ts (8)
  • 373-373: The assignment of permId using getUserHighestPermission method is a good practice for ensuring that the correct permissions are applied based on the user's highest permission level. However, it's crucial to ensure that the permissions hierarchy is well-defined and that defaultPermissions.CASTERS is appropriately set as a high-level permission to prevent unauthorized access.
  • 416-416: Similar to the previous comment, the use of getUserHighestPermission for determining permId in the symbols parser method is consistent and ensures that permissions are correctly applied. It's important to maintain consistency in permission checks across different parser methods to avoid security loopholes.
  • 466-466: Again, the consistent use of getUserHighestPermission for permission checks in the longMessage parser method is noted. This consistency across methods is crucial for maintaining a secure and predictable permission system. Ensure that all parser methods follow a similar pattern for permission checks.
  • 504-504: The use of getUserHighestPermission in the caps parser method follows the established pattern of permission checks. This consistency is key to a robust permission system. It's important to review the entire permission hierarchy to ensure that it aligns with the intended access control for various user roles.
  • 568-568: The application of getUserHighestPermission in the spam parser method continues the pattern of consistent permission checks. This approach helps in maintaining a secure moderation system by applying the correct permissions based on the user's highest role.
  • 609-609: The use of getUserHighestPermission for permission checks in the color parser method is consistent with the rest of the moderation system. This approach ensures that permissions are correctly applied, contributing to the overall security of the bot.
  • 644-644: The consistent use of getUserHighestPermission in the emotes parser method is noted. This approach is crucial for applying the correct permissions and maintaining the security of the moderation system. Ensure that the permission hierarchy is thoroughly reviewed to align with the bot's access control requirements.
  • 688-688: The use of getUserHighestPermission in the blacklist parser method is consistent with the established pattern of permission checks across the moderation system. This consistency is key to ensuring that permissions are correctly applied, enhancing the security and reliability of the bot.
src/_interface.ts (6)
  • 2-2: The import of randomUUID from node:crypto is a good addition for generating unique identifiers. Ensure that its usage, as seen with the uuid property of the Module class, adheres to the intended purpose across the application.
  • 41-41: Adding a secret flag to the settingsList property is a thoughtful approach to handling sensitive settings. This allows for better control over which settings are exposed, enhancing security.
  • 117-117: The introduction of a _scope property to the Module class aligns with the PR's objective of improving granular access control. This property, along with the scope method, facilitates better management of access rights.
  • 140-140: The initialization of _scope using both _name and the module's name in lowercase is a solid approach to ensure unique and meaningful scope identifiers.
  • 197-203: The scope method's implementation is straightforward and effective. However, the static analysis tool flagged that the use of the variable type always evaluates to true, which seems to be a misunderstanding. The conditional check on type is valid as it determines whether to append a suffix to the scope string.
  • 496-496: The getAllSettings method's approach to handling sensitive settings based on the sensitive flag is commendable. It ensures that secret settings are only included when explicitly allowed, aligning with best practices for handling sensitive information.
src/systems/songs.ts (6)
  • 29-29: The change from publicEndpoint to endpoint and adminEndpoint indicates a refinement in how endpoints are declared, likely to differentiate between public and admin-specific functionalities. Ensure that all instances where publicEndpoint was previously used are correctly updated to use either endpoint or adminEndpoint as appropriate. This change should improve clarity and security by explicitly distinguishing between public and admin endpoints.
  • 76-76: Adding scopeParent: this.scope() to the addMenu calls introduces a more granular control over access permissions. This is a significant improvement in terms of security and flexibility, allowing for better management of who can access or modify the playlist settings. Ensure that the scope() method is properly implemented and tested to handle these new access control requirements effectively.
  • 79-79: Similar to the previous comment, adding scopeParent: this.scope() for the bannedsongs menu enhances the access control mechanism. It's crucial to verify that the scope() method accurately reflects the intended access restrictions for managing banned songs.
  • 114-114: The update to the endpoint path and function signature for current.playlist.tag is a part of the broader effort to refine endpoint handling. This change should make the endpoint's purpose clearer and its usage more consistent across the system. Verify that the updated path and signature are correctly implemented in all relevant parts of the application.
  • 124-124: The modifications to the find.playlist endpoint, including the introduction of pagination and search functionality, represent a significant improvement in terms of performance and user experience. It's important to ensure that the pagination logic correctly handles edge cases, such as requests for non-existent pages or excessively large page sizes. Additionally, verify that the search and filter functionalities are thoroughly tested to prevent potential security vulnerabilities, such as SQL injection.
  • 221-221: The addition of the songs::getAllRequests endpoint with pagination support is another positive change towards enhancing the system's scalability and usability. As with the find.playlist endpoint, ensure that the pagination and filtering logic is robust and secure, particularly in handling user input.
src/events.ts (2)
  • 200-200: The addition of scopeParent: this.scope(), to the addMenu call aligns with the PR's objectives to enhance access control through improved scope management. Ensure that the scope() method is properly implemented and returns a value that is compatible with the expected scopeParent parameter.
  • 197-203: > 📝 NOTE

This review was outside the diff hunks, and no overlapping diff hunk was found. Original lines [9-9]

Given the extensive functionality encapsulated within the Events class, consider modularizing specific functionalities (e.g., handling different event types, operations) into separate classes or modules. This approach can enhance maintainability, readability, and ease future development efforts.

@@ -249,7 +249,7 @@ export type ClientToServerEventsWithNamespace = {
time: number;
}) => void) => void,
'stopwatch::update::set': (data: { id: string, isEnabled: boolean | null, time: number | null }) => void,
'stopwatch::update': (data: { id: string, isEnabled: boolean | null, time: number | null }, cb: (_err: null, data?: { isEnabled: boolean | null, time :string | null }) => void) => void,
'stopwatch::update': (data: any, cb: (_err: null, data?: { isEnabled: boolean | null, time :string | null }) => void) => void,
Copy link

Choose a reason for hiding this comment

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

The change to the stopwatch::update event handler's signature to accept data of any type introduces potential type safety issues. While flexibility in handling different data structures can be beneficial, it's important to consider the implications on type safety and code maintainability. If possible, using a more specific type or a union of types that accurately represents the expected structure of data would enhance type safety and clarity.

@@ -49,7 +51,7 @@ const checkIfDecoratorsAreLoaded = () => {
};
checkIfDecoratorsAreLoaded();

function getNameAndTypeFromStackTrace(): { name: string, type: keyof typeof systems} {
export function getNameAndTypeFromStackTrace(): { name: string, type: keyof typeof systems} {
Copy link

Choose a reason for hiding this comment

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

Exporting the getNameAndTypeFromStackTrace function is a significant change. This function seems to be a utility for determining the name and type of a system based on the call stack. It's crucial to ensure that this function is robust against potential errors, such as when stack[2].getFileName() returns null or an unexpected value. Additionally, consider adding tests for this function to cover various scenarios and edge cases.

Consider adding error handling for cases where stack[2].getFileName() might return null or an unexpected value, to prevent runtime errors.

@@ -305,17 +316,24 @@
error(this.nsp + ': Cannot initialize sockets second time');
};

// default socket listeners
adminEndpoint(this.nsp, 'settings', async (cb) => {
app.get(`/api/settings${this.nsp}`, withScope([this.scope('read'), this.scope('manage')]), async (req, res) => {
Copy link

Choose a reason for hiding this comment

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

The route handler for getting settings does not implement rate limiting. Considering this handler performs authorization, adding rate limiting would mitigate potential abuse and enhance security.

+ // Consider implementing rate limiting for this route to enhance security
app.get(`/api/settings${this.nsp}`, withScope([this.scope('read'), this.scope('manage')]), async (req, res) => {

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
app.get(`/api/settings${this.nsp}`, withScope([this.scope('read'), this.scope('manage')]), async (req, res) => {
// Consider implementing rate limiting for this route to enhance security
app.get(`/api/settings${this.nsp}`, withScope([this.scope('read'), this.scope('manage')]), async (req, res) => {

// flatten and remove category
const data = flatten(opts);

app.post(`/api/settings${this.nsp}`, withScope([this.scope('manage')]), async (req, res) => {
Copy link

Choose a reason for hiding this comment

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

Similar to the previous comment, this POST route handler for updating settings lacks rate limiting. Implementing rate limiting here is crucial for preventing abuse, especially since this endpoint modifies settings.

+ // Implement rate limiting to prevent abuse
app.post(`/api/settings${this.nsp}`, withScope([this.scope('manage')]), async (req, res) => {

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
app.post(`/api/settings${this.nsp}`, withScope([this.scope('manage')]), async (req, res) => {
// Implement rate limiting to prevent abuse
app.post(`/api/settings${this.nsp}`, withScope([this.scope('manage')]), async (req, res) => {

Comment on lines +73 to +82
@Post('/example')
async getLevelsExample(req: any) {
const firstLevelStartsAt = req.body.firstLevelStartsAt;
const nextLevelFormula = req.body.nextLevelFormula;
const xpName = req.body.xpName;
const levels = [];
for (let i = 1; i <= 21; i++) {
levels.push(this.getLevelXP(i, BigInt(firstLevelStartsAt), nextLevelFormula, true));
}
return levels.map(xp => `${Intl.NumberFormat(general.lang).format(xp)} ${xpName}`);
Copy link

Choose a reason for hiding this comment

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

The addition of the @Post('/example') decorator and getLevelsExample method introduces a new endpoint for generating level examples based on request body parameters. This is a good use of async/await for handling asynchronous operations and the use of BigInt for level calculations ensures accuracy for large numbers. However, ensure that input validation is performed on the request body to prevent potential injection attacks or errors from malformed input.

Consider adding input validation for firstLevelStartsAt, nextLevelFormula, and xpName to ensure they are of expected types and formats before processing.

src/widgets/_interface.ts Outdated Show resolved Hide resolved
src/integrations/_interface.ts Outdated Show resolved Hide resolved

class Stats extends Overlay {
showInUI = false;

sockets () {
publicEndpoint(this.nsp, 'get', async (cb) => {
endpoint([], this.nsp, 'get' as any, async (cb: any) => {
Copy link

Choose a reason for hiding this comment

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

Renaming publicEndpoint to endpoint and adjusting its usage is part of standardizing endpoint handling. Consider refining the type handling for the HTTP method parameter to avoid using any, ensuring type safety and clarity.

- endpoint([], this.nsp, 'get' as any, async (cb: any) => {
+ endpoint([], this.nsp, 'get', async (cb: any) => {

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
endpoint([], this.nsp, 'get' as any, async (cb: any) => {
endpoint([], this.nsp, 'get', async (cb: any) => {


class Polls extends Overlay {
public sockets() {
publicEndpoint(this.nsp, 'data', async (callback) => {
endpoint([], this.nsp, 'data' as any, async (callback: any) => {
Copy link

Choose a reason for hiding this comment

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

Renaming publicEndpoint to endpoint and adjusting its usage is part of standardizing endpoint handling. Consider refining the type handling for the HTTP method parameter to avoid using any, ensuring type safety and clarity.

- endpoint([], this.nsp, 'data' as any, async (callback: any) => {
+ endpoint([], this.nsp, 'data', async (callback: any) => {

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
endpoint([], this.nsp, 'data' as any, async (callback: any) => {
endpoint([], this.nsp, 'data', async (callback: any) => {


class Bets extends Overlay {
public sockets() {
publicEndpoint(this.nsp, 'data', async (callback) => {
endpoint([], this.nsp, 'data' as any, async (callback: any) => {
Copy link

Choose a reason for hiding this comment

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

Renaming publicEndpoint to endpoint and adjusting its usage is part of standardizing endpoint handling. Consider refining the type handling for the HTTP method parameter to avoid using any, ensuring type safety and clarity.

- endpoint([], this.nsp, 'data' as any, async (callback: any) => {
+ endpoint([], this.nsp, 'data', async (callback: any) => {

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
endpoint([], this.nsp, 'data' as any, async (callback: any) => {
endpoint([], this.nsp, 'data', async (callback: any) => {

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review Status

Actionable comments generated: 2

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 7f11c23 and 768f88c.
Files selected for processing (2)
  • src/_interface.ts (12 hunks)
  • src/integrations/_interface.ts (1 hunks)
Check Runs (1)
CodeQL failure (9)
  • src/_interface.ts: 319-319: This route handler performs authorization, but is not rate-limited.
  • src/_interface.ts: 335-335: This route handler performs authorization, but is not rate-limited.
Files skipped from review as they are similar to previous changes (1)
  • src/integrations/_interface.ts
Additional comments: 5
src/_interface.ts (5)
  • 2-2: The import of randomUUID from node:crypto is a good addition for generating unique identifiers. Ensure that its usage throughout the file, especially in generating UUIDs for modules and commands, adheres to best practices for uniqueness and security.
  • 41-41: Adding a secret flag to the settingsList property in the Module class is a valuable enhancement for handling sensitive settings. This allows for better control over which settings are exposed, enhancing security.
  • 114-120: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [117-140]

The introduction of a _scope property and a scope method in the Module class is a significant architectural improvement. It facilitates granular access control by allowing modules to define their own scopes. This change aligns well with the PR's objective of enhancing access control and permissions management.

  • 197-203: The implementation of the scope method is concise and effectively adds the ability to specify read or manage scopes. This method enhances the flexibility of access control by allowing more granular permissions.
  • 496-506: The handling of secret settings in the getAllSettings method is well-implemented, ensuring that sensitive settings are only included when explicitly allowed. This approach is consistent with the objective of enhancing security and privacy within the system.

Comment on lines 381 to 417
}
}
}
try {
for (const [key, value] of Object.entries(unflatten(data))) {
if (key === 'enabled' && this._enabled === null) {
// ignore enabled if we don't want to enable/disable at will
continue;
} else if (key === 'enabled') {
this.status({ state: value });
} else if (key === '__permission_based__') {
for (const vKey of Object.keys(value as any)) {
(this as any)['__permission_based__' + vKey] = (value as any)[vKey];
}
} else {
(this as any)[key] = value;
for (const [key, value] of Object.entries(unflatten(data))) {
if (key === 'enabled' && this._enabled === null) {
// ignore enabled if we don't want to enable/disable at will
continue;
} else if (key === 'enabled') {
this.status({ state: value });
} else if (key === '__permission_based__') {
for (const vKey of Object.keys(value as any)) {
(this as any)['__permission_based__' + vKey] = (value as any)[vKey];
}
}
} catch (e: any) {
error(e.stack);
if (typeof cb === 'function') {
setTimeout(() => cb(e.stack), 1000);
} else {
(this as any)[key] = value;
}
}

await watchers.check(true); // force watcher to refresh

if (typeof cb === 'function') {
setTimeout(() => cb(null), 1000);
// trigger onSettingsSave
for (const event of getFunctionList('settingsSave', this.__moduleName__.toLowerCase())) {
if (typeof (this as any)[event.fName] === 'function') {
(this as any)[event.fName]();
} else {
error(`${event.fName}() is not function in ${this._name}/${this.__moduleName__.toLowerCase()}`);
}
}
res.json({ status: 'success' });
});

adminEndpoint(this.nsp, 'set.value', async (opts, cb) => {
endpoint([
this.nsp.split('/').map(o => o.trim()).filter(String).join(':') + ':manage',
], this.nsp, 'set.value', async (opts, cb) => {
try {
(this as any)[opts.variable] = opts.value;
if (cb) {
Copy link

Choose a reason for hiding this comment

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

📝 NOTE
This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [335-409]

Similar to the previous comment, this POST route handler for updating settings lacks rate limiting. Implementing rate limiting here is crucial for preventing abuse, especially since this endpoint modifies settings.

+ // Implement rate limiting to prevent abuse
app.post(`/api/settings${this.nsp}`, withScope([this.scope('manage')]), async (req, res) => {

src/_interface.ts Fixed Show fixed Hide fixed
src/_interface.ts Fixed Show fixed Hide fixed
src/_interface.ts Dismissed Show dismissed Hide dismissed
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review Status

Actionable comments generated: 14

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 768f88c and 1ae2969.
Files selected for processing (11)
  • src/_interface.ts (11 hunks)
  • src/database/entity/quotes.ts (2 hunks)
  • src/decorators/endpoint.ts (1 hunks)
  • src/systems/alias.ts (3 hunks)
  • src/systems/cooldown.ts (4 hunks)
  • src/systems/customcommands.ts (2 hunks)
  • src/systems/howlongtobeat.ts (4 hunks)
  • src/systems/keywords.ts (1 hunks)
  • src/systems/price.ts (2 hunks)
  • src/systems/queue.ts (3 hunks)
  • src/systems/quotes.ts (1 hunks)
Check Runs (1)
CodeQL failure (9)
  • src/_interface.ts: 319-319: This route handler performs authorization, but is not rate-limited.
  • src/_interface.ts: 357-357: This route handler performs authorization, but is not rate-limited.
  • src/_interface.ts: 335-335: This route handler performs authorization, but is not rate-limited.
  • src/_interface.ts: 346-346: This route handler performs authorization, but is not rate-limited.
  • src/_interface.ts: 348-348: A property name to write to depends on a user-provided value.
  • src/decorators/endpoint.ts: 107-107: This route handler performs authorization, but is not rate-limited.
  • src/decorators/endpoint.ts: 170-170: This route handler performs authorization, but is not rate-limited.
Files skipped from review as they are similar to previous changes (3)
  • src/database/entity/quotes.ts
  • src/systems/cooldown.ts
  • src/systems/quotes.ts
Additional comments: 19
src/systems/price.ts (3)
  • 48-49: The @Get('/', 'read') decorator fetches all PriceEntity instances. This operation seems straightforward and correctly implemented. However, consider implementing pagination if the number of entities can grow significantly, to improve performance and usability.
  • 51-53: The @Get('/:id', 'read') decorator fetches a single PriceEntity by ID. Ensure proper error handling is in place if the entity with the specified ID does not exist, to return a meaningful error response to the client.
Verification successful

The review comment is verified. The getOne method in src/systems/price.ts directly returns the result of PriceEntity.findOneBy without any explicit error handling for cases where the entity does not exist. Implementing error handling in this method is recommended to return a meaningful error response to the client when the specified ID does not match any existing PriceEntity.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify error handling for non-existent PriceEntity ID
ast-grep --lang javascript --pattern $'PriceEntity.findOneBy({ id: $_ })'

Length of output: 74



Script:

#!/bin/bash
# Search for usage of PriceEntity.findOneBy across all files to verify error handling
rg 'PriceEntity\.findOneBy'

Length of output: 191



Script:

#!/bin/bash
# Display surrounding code for PriceEntity.findOneBy usage to verify error handling
rg 'PriceEntity\.findOneBy' -C 5 src/systems/price.ts

Length of output: 443

* 55-59: The `@Delete('/:id')` decorator removes a `PriceEntity` by ID. It's important to verify that the entity exists before attempting to remove it, and handle cases where the entity does not exist by returning an appropriate error response.
src/systems/howlongtobeat.ts (3)
  • 79-86: The @Get('/', 'read') decorator fetches all HowLongToBeatGame entities and enriches them with thumbnails. This operation is well-implemented, but consider adding error handling for potential database query failures and ensuring that the thumbnail fetching does not significantly impact performance.
  • 88-90: The @Get('/:id', 'read') decorator fetches a single HowLongToBeatGame entity by ID. Ensure that error handling is in place for cases where the entity does not exist, to return a meaningful error response to the client.
  • 104-108: The @Delete('/:id') decorator removes a HowLongToBeatGame entity by ID. It's important to verify that the entity exists before attempting to remove it, and handle cases where the entity does not exist by returning an appropriate error response.
src/systems/keywords.ts (3)
  • 16-16: The import of Delete, Get, and Post decorators indicates a shift towards using decorators for defining HTTP endpoints, which is a positive change for readability and maintainability.
  • 36-54: The CRUD operations for Keywords have been refactored to use the new decorators. This approach enhances readability and maintainability. However, ensure that proper authentication and authorization checks are in place to prevent unauthorized access.
  • 55-92: The CRUD operations for KeywordGroups have also been refactored to use decorators. Similar to the Keywords endpoints, verify that authentication and authorization checks are properly implemented to secure these endpoints.
src/systems/customcommands.ts (3)
  • 17-17: The import of Post, Get, and Delete decorators for CustomCommands is a positive change, aligning with the approach taken in Keywords. It improves the structure and readability of the code.
  • 51-82: The CRUD operations for CustomCommands have been refactored using decorators. Ensure that authentication and authorization checks are in place for these operations to secure the endpoints.
  • 83-120: The CRUD operations for CommandsGroup have been refactored similarly. As with the previous comments, verify that proper security measures are implemented to protect these endpoints.
src/systems/alias.ts (2)
  • 13-13: The import of Delete, Get, and Post decorators from '~/decorators/endpoint.js' is correctly added to support the new API endpoint decorators for CRUD operations on AliasEntity and AliasGroup. This aligns with the PR objectives of enhancing the architecture for handling settings and endpoints.
  • 83-100: The findAllGroups method uses a Promise to resolve the list of AliasGroup and AliasEntity. This method demonstrates an interesting approach to combining data from two different sources. However, there's a potential performance concern with the use of Promise.all for fetching both groups and aliases without any pagination or limit, which could lead to performance issues if there are a large number of records.

Consider implementing pagination or limiting the number of records fetched to avoid potential performance bottlenecks.

src/_interface.ts (5)
  • 2-2: The addition of randomUUID from node:crypto is a good practice for generating unique identifiers. Ensure that its usage within the Module class (e.g., for uuid property initialization) aligns with the intended purpose of providing unique module identifiers.
  • 41-41: Adding a secret flag to the settingsList property in the Module class is a significant improvement for handling sensitive settings securely. This change enhances the security by allowing certain settings to be marked as sensitive, which can then be handled appropriately in the settings management logic.
  • 114-120: > 📝 NOTE

This review was outside the diff hunks and was mapped to the diff hunk with the greatest overlap. Original lines [117-140]

The introduction of a _scope property and a scope method in the Module class is a crucial enhancement for implementing granular access control. This allows for better management of access rights at a more detailed level, improving the security and flexibility of the system. It's important to ensure that the scope strings are constructed and used consistently across the application.

  • 197-203: The scope method implementation is a key part of the granular access control feature. It dynamically constructs scope strings based on the module name and optional type. This method enhances the flexibility and security of access control by allowing for more precise specification of access rights.
  • 496-506: The implementation of getAllSettings with the secret and sensitive flags is a thoughtful approach to handling sensitive settings securely. This method ensures that secret settings are only included in the response if the request has the appropriate scope, enhancing the security of the settings management system.

Comment on lines 58 to 78
@Post('/')
saveOne(req: any) {
return AliasEntity.create(req.body).save();
}
@Get('/', 'read')
findAll() {
return AliasEntity.find();
}
@Get('/:id', 'read')
findOne(req: any) {
return AliasEntity.findOneBy({ id: req.params.id });
}
@Delete('/:id')
async removeOne(params: any) {
const al = await AliasEntity.findOneBy({ id: params.id });
if (al) {
await al.remove();
}
}
Copy link

Choose a reason for hiding this comment

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

The addition of API endpoint decorators (@Post, @Get, @Delete) for CRUD operations on AliasEntity is a significant improvement. It enhances the modularity and readability of the code by clearly defining the HTTP methods and paths for each operation. However, ensure that proper error handling and validation are implemented within these methods to prevent potential security issues or data integrity problems.

Consider adding input validation and error handling within these methods to ensure data integrity and security.

Comment on lines 77 to 122
@Post('/', '/systems/groups/alias')
saveOneGroup(req: any) {
return AliasGroup.create(req.body).save();
}
@Get('/', 'read', '/systems/groups/alias')
findAllGroups() {
return new Promise((resolve, reject) => {
Promise.all([AliasGroup.find(), AliasEntity.find()]).then(([groupsList, aliases]) => {
for (const item of aliases) {
if (item.group && !groupsList.find(o => o.name === item.group)) {
// we dont have any group options -> create temporary group
const group = new AliasGroup();
group.name = item.group;
group.options = {
filter: null,
permission: null,
};
groupsList = [
...groupsList,
group,
];
const group = new AliasGroup();
group.name = item.group;
group.options = {
filter: null,
permission: null,
};
groupsList = [
...groupsList,
group,
];
}
}
}
cb(null, groupsList);
});
adminEndpoint('/systems/alias', 'generic::getAll', async (cb) => {
cb(null, await AliasEntity.find());
});
adminEndpoint('/systems/alias', 'generic::getOne', async (id, cb) => {
cb(null, await AliasEntity.findOneBy({ id }));
});
adminEndpoint('/systems/alias', 'generic::deleteById', async (id, cb) => {
try {
const alias = await AliasEntity.findOneBy({ id });
if (!alias) {
throw new Error(`Alias ${id} not found`);
}
await alias.remove();
cb(null);
} catch (e) {
cb(e as Error);
}
});
adminEndpoint('/systems/alias', 'generic::save', async (item, cb) => {
try {
cb(null, await AliasEntity.create(item).save());
} catch (e) {
cb(e, undefined);
}
resolve(groupsList);
});
});
}
@Get('/:name', 'read', '/systems/groups/alias')
findOneGroup(req: any) {
return AliasGroup.findOneBy({ name: req.params.name });
}
@Delete('/:name', '/systems/groups/alias')
async removeOneGroup(params: any) {
const al = await AliasGroup.findOneBy({ name: params.name });
if (al) {
await al.remove();
}
}
Copy link

Choose a reason for hiding this comment

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

Similarly, the addition of API endpoint decorators for CRUD operations on AliasGroup follows the same pattern as for AliasEntity. This consistency is good for maintainability. Again, it's crucial to ensure that these methods include proper error handling and validation.

Ensure that input validation and error handling are implemented for these methods as well, to maintain data integrity and security.

Comment on lines 319 to 329
app.get(`/api/settings${this.nsp}`, withScope([this.scope('read'), this.scope('manage')]), async (req, res) => {
try {
cb(null, await this.getAllSettings(), await this.getUI());
res.json({
status: 'success',
data: {
settings: await this.getAllSettings(
undefined, req.headers?.scopes?.includes(`${this.nsp.split('/').map(o => o.trim()).filter(String).join(':')}:sensitive`),
),
ui: await this.getUI(),
},
});
Copy link

Choose a reason for hiding this comment

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

This route handler performs authorization but is not rate-limited. Considering this handler performs sensitive operations related to settings management, adding rate limiting would mitigate potential abuse and enhance security.

+ // Consider implementing rate limiting for this route to enhance security
app.get(`/api/settings${this.nsp}`, withScope([this.scope('read'), this.scope('manage')]), async (req, res) => {

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
app.get(`/api/settings${this.nsp}`, withScope([this.scope('read'), this.scope('manage')]), async (req, res) => {
try {
cb(null, await this.getAllSettings(), await this.getUI());
res.json({
status: 'success',
data: {
settings: await this.getAllSettings(
undefined, req.headers?.scopes?.includes(`${this.nsp.split('/').map(o => o.trim()).filter(String).join(':')}:sensitive`),
),
ui: await this.getUI(),
},
});
// Consider implementing rate limiting for this route to enhance security
app.get(`/api/settings${this.nsp}`, withScope([this.scope('read'), this.scope('manage')]), async (req, res) => {
try {
res.json({
status: 'success',
data: {
settings: await this.getAllSettings(
undefined, req.headers?.scopes?.includes(`${this.nsp.split('/').map(o => o.trim()).filter(String).join(':')}:sensitive`),
),
ui: await this.getUI(),
},
});

Comment on lines 335 to 343
app.get(`/api/settings${this.nsp}/:variable`, withScope([this.scope('read'), this.scope('manage')]), async (req, res) => {
try {
res.json({
status: 'success',
data: await (this as any)[req.params.variable],
});
} catch (e: any) {
res.status(500).json({ error: e.stack, status: 'error' });
}
Copy link

Choose a reason for hiding this comment

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

Similar to the previous comment, this GET route handler for fetching specific settings lacks rate limiting. Implementing rate limiting here is crucial for preventing abuse, especially since this endpoint accesses potentially sensitive settings.

+ // Implement rate limiting to prevent abuse
app.get(`/api/settings${this.nsp}/:variable`, withScope([this.scope('read'), this.scope('manage')]), async (req, res) => {

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
app.get(`/api/settings${this.nsp}/:variable`, withScope([this.scope('read'), this.scope('manage')]), async (req, res) => {
try {
res.json({
status: 'success',
data: await (this as any)[req.params.variable],
});
} catch (e: any) {
res.status(500).json({ error: e.stack, status: 'error' });
}
// Implement rate limiting to prevent abuse
app.get(`/api/settings${this.nsp}/:variable`, withScope([this.scope('read'), this.scope('manage')]), async (req, res) => {
try {
res.json({
status: 'success',
data: await (this as any)[req.params.variable],
});
} catch (e: any) {
res.status(500).json({ error: e.stack, status: 'error' });
}

Comment on lines 346 to 354
app.post(`/api/settings${this.nsp}/:variable`, withScope([this.scope('manage')]), async (req, res) => {
try {
(this as any)[req.params.variable] = req.body.value;
res.json({
status: 'success',
});
} catch (e: any) {
res.status(500).json({ error: e.stack, status: 'error' });
}
Copy link

Choose a reason for hiding this comment

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

This POST route handler for updating specific settings also lacks rate limiting. Given that this endpoint modifies settings, implementing rate limiting is essential for security and to prevent potential abuse.

+ // Implement rate limiting to prevent abuse
app.post(`/api/settings${this.nsp}/:variable`, withScope([this.scope('manage')]), async (req, res) => {

Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation.

Suggested change
app.post(`/api/settings${this.nsp}/:variable`, withScope([this.scope('manage')]), async (req, res) => {
try {
(this as any)[req.params.variable] = req.body.value;
res.json({
status: 'success',
});
} catch (e: any) {
res.status(500).json({ error: e.stack, status: 'error' });
}
// Implement rate limiting to prevent abuse
app.post(`/api/settings${this.nsp}/:variable`, withScope([this.scope('manage')]), async (req, res) => {
try {
(this as any)[req.params.variable] = req.body.value;
res.json({
status: 'success',
});
} catch (e: any) {
res.status(500).json({ error: e.stack, status: 'error' });
}

src/systems/customcommands.ts Show resolved Hide resolved
src/systems/price.ts Show resolved Hide resolved
src/systems/queue.ts Outdated Show resolved Hide resolved
src/systems/queue.ts Outdated Show resolved Hide resolved
src/systems/howlongtobeat.ts Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 1ae2969 and fd83265.
Files selected for processing (3)
  • src/overlays/_interface.ts (1 hunks)
  • src/systems/queue.ts (3 hunks)
  • src/widgets/_interface.ts (1 hunks)
Files skipped from review as they are similar to previous changes (2)
  • src/overlays/_interface.ts
  • src/widgets/_interface.ts
Additional comments: 4
src/systems/queue.ts (4)
  • 10-10: The addition of Get and Post decorators from ~/decorators/endpoint.js aligns with the PR's objective to enhance API request handling through architectural improvements. This change introduces a more declarative way of defining HTTP endpoints, which is a positive step towards improving the codebase's modularity and readability.
  • 40-47: The getAll method, decorated with @Get, is a clear and concise way to handle GET requests for the queue. It demonstrates good use of async/await for asynchronous operations and conditional logic based on the action parameter. However, it's important to ensure that the req.query._action parameter is validated or sanitized to prevent potential security vulnerabilities, such as injection attacks.
Verification successful

The verification process has confirmed that there is no explicit input validation or sanitization for req.query._action in the provided context from the queue.ts file. The direct use of this parameter in conditional logic without any form of validation or sanitization could potentially expose the application to security vulnerabilities, such as injection attacks. It is recommended to implement input validation or sanitization as a best practice to mitigate such risks.

Scripts Executed

The following scripts were executed for the analysis:


Script:

#!/bin/bash
# Verify if there's input validation for req.query._action in upstream code
rg "req.query._action" --context 5

Length of output: 957

* 48-86: The `postAction` method, decorated with `@Post`, handles various actions based on the `_action` query parameter. This method demonstrates a structured approach to handling different actions within a single endpoint. However, there are a few points to consider: 1. Similar to the `getAll` method, ensure that `req.query._action` and `req.body` are properly validated or sanitized. 2. The method could benefit from breaking down into smaller functions for each action to improve readability and maintainability. 3. The use of `await` inside loops (lines 62-73 and 78-83) can lead to performance issues. Consider refactoring to use `Promise.all` for concurrent execution where possible.
- for (const user of data.username) {
+ await Promise.all(data.username.map(async (user) => {
  • 151-152: The conditional logic within the join method for determining user eligibility based on subscriber status is clear and straightforward. However, consider extracting this logic into a separate method or utility function to enhance modularity and potentially reuse this logic elsewhere in the codebase.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Review Status

Actionable comments generated: 0

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between fd83265 and 2f2805f.
Files selected for processing (2)
  • src/decorators/endpoint.ts (1 hunks)
  • src/systems/queue.ts (4 hunks)
Additional comments: 6
src/decorators/endpoint.ts (3)
  • 11-80: The Post decorator implementation introduces a retry mechanism for registering endpoints, which is a good resilience feature. However, there are a few areas for improvement and considerations:
  1. Error Handling: The error handling within the route handler (lines 37-76) is well-structured, but it might be beneficial to log the error details for better debugging.
  2. Rate Limiting: As previously mentioned by the security bot and other comments, rate limiting is missing. Implementing rate limiting is crucial for preventing abuse and ensuring the stability of the application. Consider integrating a rate-limiting middleware.
  3. Zod Validation: The use of Zod for request body validation (lines 45-47) is a good practice for ensuring data integrity. Ensure that all necessary fields are validated to prevent potential issues.
+ // Consider adding a rate-limiting middleware to enhance security
+ app.use(rateLimit({
+   windowMs: 15 * 60 * 1000, // 15 minutes
+   max: 100 // limit each IP to 100 requests per windowMs
+ }));

Consider verifying the integration of rate limiting across all endpoints and ensuring comprehensive error logging for better maintainability.

  • 82-148: Similar to the Post decorator, the Get decorator also lacks rate limiting and could benefit from enhanced error logging for debugging purposes. The implementation follows a similar pattern with retries for endpoint registration and scope-based access control, which is a good practice for granular permissions management.

Consider applying the same rate-limiting and error logging enhancements as recommended for the Post decorator to ensure consistency and security across all endpoint types.

  • 150-198: The Delete decorator shares the same considerations as the Post and Get decorators regarding the absence of rate limiting and the potential for enhanced error logging. The implementation pattern is consistent, which is good for maintainability, but these enhancements would further improve the robustness and security of the application.

Applying the recommended rate-limiting and error logging enhancements to the Delete decorator as well would ensure a uniform approach to security and error handling across all HTTP methods.

src/systems/queue.ts (3)
  • 11-11: The addition of Get and Post decorators from ~/decorators/endpoint.js aligns with the PR's objective to refactor socket functions into API endpoint methods. This change enhances the modularity and readability of the code by clearly defining HTTP endpoints.
  • 41-91: The implementation of API endpoint methods getAll and postAction using the Get and Post decorators respectively is a significant improvement in terms of code organization and readability. A few points to consider:
  1. Error Handling: Ensure that all potential errors are appropriately handled within these methods, especially when interacting with the database or parsing request bodies.
  2. Input Validation: The use of Zod for input validation in postAction (lines 49-53) is commendable. Ensure that all endpoints have adequate input validation to prevent issues related to malformed or malicious data.

Consider verifying the comprehensive error handling and input validation across all newly introduced API endpoint methods to ensure robustness and security.

  • 156-156: The logic within the join method has been updated to consider the eligibilityAll and eligibilitySubscribers settings for determining user eligibility to join the queue. This change improves the flexibility of the queue system by allowing for more granular control over who can join the queue based on their subscriber status.

@sogehige sogehige force-pushed the granularAccess branch 2 times, most recently from a727ecb to aea4b2d Compare April 3, 2024 12:20
src/decorators/endpoint.ts Fixed Show fixed Hide fixed
addScope(`${type}:${name.toLowerCase()}:sensitive`);
}

app.post(generatedEndpoint, withScope(scopes), async (req, res) => {

Check failure

Code scanning / CodeQL

Missing rate limiting High

This route handler performs
authorization
, but is not rate-limited.
src/decorators/endpoint.ts Fixed Show fixed Hide fixed
if (generatedEndpoint.endsWith('/')) {
generatedEndpoint = generatedEndpoint.slice(0, -1);
}
app.get(generatedEndpoint, withScope(scopes, params.scope === 'public'), async (req, res) => {

Check failure

Code scanning / CodeQL

Missing rate limiting High

This route handler performs
authorization
, but is not rate-limited.
src/permissions.ts Fixed Show fixed Hide fixed
src/decorators/endpoint.ts Fixed Show fixed Hide fixed
Copy link

@github-advanced-security github-advanced-security bot left a comment

Choose a reason for hiding this comment

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

CodeQL found more than 20 potential problems in the proposed changes. Check the Files changed tab for more details.

@sogehige sogehige force-pushed the granularAccess branch 2 times, most recently from b412cb6 to b05ba88 Compare May 28, 2024 20:07

(function initializeMessageParserAPI() {
if (!app) {
setTimeout(() => initializeMessageParserAPI(), 100);
return;
}

app.post('/api/core/parse', adminMiddleware, async (req, res) => {
app.post('/api/core/parse', withScope(['dashboard:manage']), async (req, res) => {

Check failure

Code scanning / CodeQL

Missing rate limiting High

This route handler performs
authorization
, but is not rate-limited.
src/overlays/countdown.ts Fixed Show fixed Hide fixed
src/overlays/stopwatch.ts Fixed Show fixed Hide fixed
@@ -49,7 +49,7 @@
return;
}

app.get('/api/stats/current', adminMiddleware, async (__, res) => {
app.get('/api/stats/current', withScope(['dashboard:read']), async (__, res) => {

Check failure

Code scanning / CodeQL

Missing rate limiting High

This route handler performs
authorization
, but is not rate-limited.
@@ -93,7 +93,7 @@
}
});

app.get('/api/stats/latest', adminMiddleware, async (__, res) => {
app.get('/api/stats/latest', withScope(['dashboard:read']), async (__, res) => {

Check failure

Code scanning / CodeQL

Missing rate limiting High

This route handler performs
authorization
, but is not rate-limited.
}
});

app.post(`/api/settings${this.nsp}/:variable`, withScope([`${this._name}:manage`]), async (req, res) => {

Check failure

Code scanning / CodeQL

Missing rate limiting High

This route handler performs
authorization
, but is not rate-limited.
}
});

app.post(`/api/settings${this.nsp}`, withScope([`${this._name}:manage`]), async (req, res) => {

Check failure

Code scanning / CodeQL

Missing rate limiting High

This route handler performs
authorization
, but is not rate-limited.
for (const scope of scopes) {
addScope(scope);
}
app.patch(generatedEndpoint, withScope(scopes), async (req, res) => {

Check failure

Code scanning / CodeQL

Missing rate limiting High

This route handler performs
authorization
, but is not rate-limited.
});
if (continousPlayMutex[id]) {
// increase validity if alert is still in overlay queue prepared to play
continousPlayMutex[id] = Date.now() + 5000;

Check failure

Code scanning / CodeQL

Remote property injection High

A property name to write to depends on a
user-provided value
.
});
if (continousPlayMutex[id]) {
// release mutex
delete continousPlayMutex[id];

Check failure

Code scanning / CodeQL

Remote property injection High

A property name to write to depends on a
user-provided value
.
opts.order.orderBy = opts.order.orderBy.split('.').map(o => `"${o}"`).join('.');
query.orderBy(opts.order.orderBy, opts.order.sortOrder);
} else {
query.orderBy({ [opts.order?.orderBy]: opts.order?.sortOrder });

Check failure

Code scanning / CodeQL

Remote property injection High

A property name to write to depends on a
user-provided value
.
query.andWhere(new Brackets(w => {
if (AppDataSource.options.type === 'postgres') {
if (filter.operation === 'contains') {
w.where(`CAST("user"."${filter.columnName}" AS TEXT) like :${filter.columnName}`, { [filter.columnName]: `%${filter.value}%` });

Check failure

Code scanning / CodeQL

Remote property injection High

A property name to write to depends on a
user-provided value
.
if (filter.operation === 'contains') {
w.where(`CAST("user"."${filter.columnName}" AS TEXT) like :${filter.columnName}`, { [filter.columnName]: `%${filter.value}%` });
} else if (filter.operation === 'equal') {
w.where(`"user"."${filter.columnName}" = :${filter.columnName}`, { [filter.columnName]: filter.value });

Check failure

Code scanning / CodeQL

Remote property injection High

A property name to write to depends on a
user-provided value
.
} else if (filter.operation === 'equal') {
w.where(`"user"."${filter.columnName}" = :${filter.columnName}`, { [filter.columnName]: filter.value });
} else if (filter.operation === 'notEqual') {
w.where(`"user"."${filter.columnName}" != :${filter.columnName}`, { [filter.columnName]: filter.value });

Check failure

Code scanning / CodeQL

Remote property injection High

A property name to write to depends on a
user-provided value
.
} else if (filter.operation === 'notEqual') {
w.where(`"user"."${filter.columnName}" != :${filter.columnName}`, { [filter.columnName]: filter.value });
} else if (filter.operation === 'greaterThanOrEqual') {
w.where(`"user"."${filter.columnName}" >= :${filter.columnName}`, { [filter.columnName]: filter.value });

Check failure

Code scanning / CodeQL

Remote property injection High

A property name to write to depends on a
user-provided value
.
} else if (filter.operation === 'equal') {
w.where(`\`user\`.\`${filter.columnName}\` = :${filter.columnName}`, { [filter.columnName]: filter.value });
} else if (filter.operation === 'notEqual') {
w.where(`\`user\`.\`${filter.columnName}\` != :${filter.columnName}`, { [filter.columnName]: filter.value });

Check failure

Code scanning / CodeQL

Remote property injection High

A property name to write to depends on a
user-provided value
.
} else if (filter.operation === 'notEqual') {
w.where(`\`user\`.\`${filter.columnName}\` != :${filter.columnName}`, { [filter.columnName]: filter.value });
} else if (filter.operation === 'greaterThanOrEqual') {
w.where(`\`user\`.\`${filter.columnName}\` >= :${filter.columnName}`, { [filter.columnName]: filter.value });

Check failure

Code scanning / CodeQL

Remote property injection High

A property name to write to depends on a
user-provided value
.
} else if (filter.operation === 'greaterThanOrEqual') {
w.where(`\`user\`.\`${filter.columnName}\` >= :${filter.columnName}`, { [filter.columnName]: filter.value });
} else if (filter.operation === 'greaterThan') {
w.where(`\`user\`.\`${filter.columnName}\` > :${filter.columnName}`, { [filter.columnName]: filter.value });

Check failure

Code scanning / CodeQL

Remote property injection High

A property name to write to depends on a
user-provided value
.
} else if (filter.operation === 'greaterThan') {
w.where(`\`user\`.\`${filter.columnName}\` > :${filter.columnName}`, { [filter.columnName]: filter.value });
} else if (filter.operation === 'lessThanOrEqual') {
w.where(`\`user\`.\`${filter.columnName}\` <= :${filter.columnName}`, { [filter.columnName]: filter.value });

Check failure

Code scanning / CodeQL

Remote property injection High

A property name to write to depends on a
user-provided value
.
} else if (filter.operation === 'lessThanOrEqual') {
w.where(`\`user\`.\`${filter.columnName}\` <= :${filter.columnName}`, { [filter.columnName]: filter.value });
} else if (filter.operation === 'lessThan') {
w.where(`\`user\`.\`${filter.columnName}\` < :${filter.columnName}`, { [filter.columnName]: filter.value });

Check failure

Code scanning / CodeQL

Remote property injection High

A property name to write to depends on a
user-provided value
.
id = spotifyUri.replace('spotify:track:', '');
} else {
const regex = new RegExp('\\S+open\\.spotify\\.com\\/track\\/(\\w+)(.*)?', 'gi');
const exec = regex.exec(spotifyUri as unknown as string);

Check failure

Code scanning / CodeQL

Polynomial regular expression used on uncontrolled data High

This
regular expression
that depends on
a user-provided value
may run slow on strings with many repetitions of '!'.
@sogehige sogehige merged commit 14b458b into master Jun 20, 2024
17 of 18 checks passed
@sogehige sogehige deleted the granularAccess branch June 20, 2024 17:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant