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

fix: several issues with using auth() in @default #1088

Merged
merged 1 commit into from
Mar 7, 2024
Merged

Conversation

ymc9
Copy link
Member

@ymc9 ymc9 commented Mar 7, 2024

  • Make generated TS field optional if it has a default
  • Handle the difference between save and unsafe Prisma mutation

Summary by CodeRabbit

  • New Features
    • Enhanced support for @default(auth()) attribute handling, including better default value management for fields and foreign key fields.
    • Introduced new utility functions for handling unsafe mutations and identifying auto-increment ID fields.
    • Added logic for better differentiation between foreign key fields and relation fields.
    • Improved handling of relation fields in model metadata generation.
  • Refactor
    • Refactored policy handling logic to include an updated isUnsafeMutate function.
    • Updated PrismaSchemaGenerator to refine the handling of default values with auth() annotations.
    • Renamed and updated logic in the schema enhancer for better clarity and functionality.
  • Tests
    • Added integration tests for new and enhanced functionalities, particularly focusing on auth() field optionality and scenarios involving a mix of safe and unsafe default values.
  • Chores
    • Introduced enhancer-utils.ts for specific utility functions like isDefaultWithAuth.
    • Added a property to SchemaLoadOptions to support additional source files during schema loading.

- Make generated TS field optional if it has a default
- Handle the difference between save and unsafe Prisma mutation
Copy link
Contributor

coderabbitai bot commented Mar 7, 2024

Walkthrough

Walkthrough

The recent updates focus on enhancing clarity, functionality, and security across various components of the system. Key improvements include clearer differentiation between foreign key fields and relation fields, advanced handling of default values with authentication attributes, and refined logic for identifying unsafe mutations. Additionally, new utilities and tests have been introduced to support these enhancements, ensuring a more robust and intuitive framework for managing data models, authentication, and policy enforcement.

Changes

File Path Change Summary
.../src/cross/model-meta.ts Clarified comments for relationField and foreignKeyMapping to distinguish between foreign key fields and relation fields.
.../runtime/src/enhancements/default-auth.ts Enhanced handling of default values for fields with @default(auth()), including new functions requireField and isUnsafeMutate, and adjustments for foreign key fields.
.../runtime/src/enhancements/policy/handler.ts Refactored isUnsafeMutate to a standalone function in utils with an additional parameter and integrated isAutoIncrementIdField logic.
.../runtime/src/enhancements/utils.ts Introduced isUnsafeMutate and isAutoIncrementIdField functions.
.../schema/src/plugins/enhancer/enhance/index.ts
.../schema/src/plugins/enhancer/enhancer-utils.ts
Added isDefaultWithAuth function, updated logic for handling delegate models and auth attributes in default models, and introduced handling based on delegate model presence.
.../schema/src/plugins/prisma/schema-generator.ts Refactored handling of auth() in default values, making fields optional in logical mode and adjusting the method for checking isDefaultWithAuth.
.../schema/tests/schema/validation/attribute-validation.test.ts Cleaned up test cases and refactored function calls.
.../sdk/src/model-meta-generator.ts
.../sdk/src/utils.ts
Enhanced functionality for handling relation fields and added utility functions for extracting foreign key and relation fields.
.../testtools/src/schema.ts Added extraSourceFiles property to SchemaLoadOptions for additional file handling during schema loading.
tests/integration/tests/enhancements/with-policy/auth.test.ts Introduced tests for default auth() field optionality and mixed safe-unsafe scenarios.

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:

Note: Auto-reply has been disabled for this repository by the repository owner. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • 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 tests 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 tests.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

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 a review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @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.
  • The JSON schema for the configuration file is available here.
  • 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/coderabbit-overrides.v2.json

CodeRabbit Discord Community

Join our Discord Community to get help, request features, and share feedback.

Copy link
Contributor

@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: 5

Configuration used: CodeRabbit UI

Commits Files that changed from the base of the PR and between 2e81a08 and 5b3bc1d.
Files selected for processing (12)
  • packages/runtime/src/cross/model-meta.ts (1 hunks)
  • packages/runtime/src/enhancements/default-auth.ts (3 hunks)
  • packages/runtime/src/enhancements/policy/handler.ts (3 hunks)
  • packages/runtime/src/enhancements/utils.ts (2 hunks)
  • packages/schema/src/plugins/enhancer/enhance/index.ts (4 hunks)
  • packages/schema/src/plugins/enhancer/enhancer-utils.ts (1 hunks)
  • packages/schema/src/plugins/prisma/schema-generator.ts (3 hunks)
  • packages/schema/tests/schema/validation/attribute-validation.test.ts (3 hunks)
  • packages/sdk/src/model-meta-generator.ts (3 hunks)
  • packages/sdk/src/utils.ts (1 hunks)
  • packages/testtools/src/schema.ts (2 hunks)
  • tests/integration/tests/enhancements/with-policy/auth.test.ts (1 hunks)
Files skipped from review due to trivial changes (1)
  • packages/schema/tests/schema/validation/attribute-validation.test.ts
Additional comments: 17
packages/schema/src/plugins/enhancer/enhancer-utils.ts (1)
  • 5-20: The implementation of isDefaultWithAuth function correctly identifies if a field attribute is a @default with auth() invocation. This addition aligns with the PR's objectives to improve handling of default values, especially with auth() annotations.
packages/runtime/src/enhancements/utils.ts (1)
  • 28-43: The isUnsafeMutate function correctly identifies unsafe mutations by checking if the mutation arguments include auto-increment ID fields or foreign keys. This logic is crucial for maintaining data integrity and security. The function's implementation aligns with the PR's objectives to differentiate between safe and unsafe Prisma mutations.

The isAutoIncrementIdField function accurately identifies if a field is an auto-increment ID field. This utility function is essential for the isUnsafeMutate function to determine unsafe mutations.

Both functions are well-implemented and contribute to the PR's goals of enhancing mutation safety checks.

packages/runtime/src/cross/model-meta.ts (1)
  • 78-85: The updated comments and descriptions for relationField and foreignKeyMapping within the FieldInfo type provide clearer differentiation between foreign key fields and relation fields. These clarifications are beneficial for developers working with the codebase, enhancing understandability and maintainability.
packages/runtime/src/enhancements/default-auth.ts (1)
  • 91-137: > 📝 NOTE

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

The enhancements in default-auth.ts for handling default values with @default(auth()) are well-implemented. The use of requireField and isUnsafeMutate functions improves the robustness of setting default values, especially for foreign key fields. The logic to conditionally set default values based on whether a mutation is considered unsafe is a significant improvement, aligning with the PR's objectives to ensure data integrity and security.

One area of improvement is to ensure that the handling of foreign key fields and the construction of the { connect: { ... } } payload are thoroughly tested, especially in edge cases where relation fields might have complex mappings.

packages/testtools/src/schema.ts (1)
  • 124-124: The addition of the extraSourceFiles property to SchemaLoadOptions is a useful enhancement that supports additional file handling during schema loading. This change enables more flexible testing scenarios by allowing the inclusion of extra source files directly through the schema loading options.
packages/sdk/src/model-meta-generator.ts (2)
  • 35-35: The import of getRelationField is correctly added to support the new functionality related to relation fields handling. This aligns with the PR objectives of enhancing the codebase to support changes in handling default values and relation fields.
  • 251-255: The addition of logic to handle relation fields in the writeFields function is a significant improvement. It ensures that relation fields are correctly identified and their related information is written, enhancing the framework's flexibility and developer experience. However, it's important to ensure that the getRelationField function is thoroughly tested, especially in edge cases where a field might not have a direct relation field or in complex relation scenarios.
packages/sdk/src/utils.ts (2)
  • 284-304: The addition of the getForeignKeyFields function is a valuable enhancement for extracting foreign key fields from relation fields. This function will facilitate more granular control and understanding of data model relationships, which is crucial for the framework's integrity and developer usability. Ensure comprehensive testing is conducted, particularly for data models with complex relationships and multiple foreign keys.
  • 306-321: The getRelationField function is a crucial addition for identifying the relation field associated with a given foreign key field. This functionality enhances the framework's ability to handle data model relationships more effectively. Similar to the getForeignKeyFields function, it's important to ensure this function is well-tested across various scenarios, including those with complex or nested relationships.
packages/schema/src/plugins/enhancer/enhance/index.ts (3)
  • 30-30: The import of isDefaultWithAuth from ../enhancer-utils is a good addition, ensuring that the logic for checking default values with auth() is encapsulated and reusable.
  • 39-39: The logic to determine if a logical Prisma client is needed by calling needsLogicalClient is clear and modular, improving the maintainability of the code.
  • 90-105: The implementation of needsLogicalClient, hasDelegateModel, and hasAuthInDefault functions is logically sound and aligns with the PR's objectives to enhance handling of default values and delegate models. These functions collectively improve the framework's flexibility and safety.
tests/integration/tests/enhancements/with-policy/auth.test.ts (2)
  • 538-572: The test case Default auth() field optionality correctly demonstrates the intended behavior of making fields optional if they have a default value specified using auth(). However, it's important to ensure that the extraSourceFiles configuration and the simulated usage in main.ts accurately reflect real-world usage patterns and are correctly integrated into the test suite.
  • Ensure that the extraSourceFiles configuration is properly handled by the test suite setup and that the content of main.ts is executed as part of the test.
  • Verify that the Prisma client and the enhance function are correctly imported and used within main.ts.
  • Confirm that the absence of author and authorId in the db.post.create call does not lead to any runtime errors or unexpected behavior, given that these fields are made optional by the default auth().id.
  • 574-619: The test case Default auth() safe unsafe mix aims to validate the differentiation between safe and unsafe Prisma mutations in the context of using auth() within @default annotations. This test case is crucial for ensuring data integrity and security. However, there are a few points to consider:
  • The test setup involves creating a User and Stats model instances before testing the creation of a Post model instance with a default auth().id and a relation to Stats. It's important to ensure that the logic for determining whether a mutation is safe or unsafe is accurately represented in this test.
  • The distinction between "safe" and "unsafe" mutations in this context should be clearly documented within the test case or linked to the relevant documentation or code comments for clarity.
  • Verify that the test accurately captures the intended behavior and edge cases for safe and unsafe mutations, especially in scenarios where the default value is derived from the auth() function.
packages/schema/src/plugins/prisma/schema-generator.ts (2)
  • 498-513: The logic for making fields optional in logical mode when they have a @default with auth() or are foreign key fields related to such fields has been updated. This change aligns with the PR's objective to improve handling of default values with auth() annotations. However, it's crucial to ensure that this logic does not inadvertently make fields optional that should remain required for data integrity purposes.
  • Ensure that making fields optional does not conflict with the data model's integrity requirements, especially in scenarios where a field should not be optional despite having a default value.
  • Verify that this change is consistently applied across all relevant parts of the codebase to maintain uniform behavior.
  • 518-518: The filter condition to exclude @default attributes with auth() from being handled by Prisma directly is a critical part of ensuring that default values with auth() are processed correctly outside of Prisma. This change is necessary to support the PR's objectives and ensures that the framework can handle these default values in a more controlled manner.
  • Confirm that all instances where @default with auth() should be handled outside Prisma are correctly identified and excluded by this filter.
  • Review related code to ensure that the logic for handling these default values outside of Prisma is robust and covers all necessary cases.
packages/runtime/src/enhancements/policy/handler.ts (1)
  • 694-694: The refactoring of isUnsafeMutate to a standalone function in ../utils and its usage here appears to be a positive change for modularity and reusability. Ensure that the implementation in ../utils correctly handles all edge cases related to determining unsafe mutations and integrates well with the policy handling logic.

Comment on lines 27 to 33
import { execPackage } from '../../../utils/exec-utils';
import { trackPrismaSchemaError } from '../../prisma';
import { PrismaSchemaGenerator } from '../../prisma/schema-generator';
import { isDefaultWithAuth } from '../enhancer-utils';

// information of delegate models and their sub models
type DelegateInfo = [DataModel, DataModel[]][];
Copy link
Contributor

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 no overlapping diff hunk was found. Original lines [48-48]

Detected multiple instances where user input might be indirectly influencing file paths through variables like outDir. Ensure that outDir and similar variables are sanitized or validated to prevent path traversal vulnerabilities.

- path.join(outDir, 'prisma.d.ts')
+ path.join(sanitizePath(outDir), 'prisma.d.ts')

Note: Apply similar changes to all instances where outDir is used in path operations.

Also applies to: 56-56, 64-64, 110-110, 136-136, 148-148, 163-163


📝 NOTE
This review was outside the diff hunks, and no overlapping diff hunk was found. Original lines [329-331]

The use of dynamically constructed regular expressions in removeCreateFromDelegateInput and removeDiscriminatorFromConcreteInput functions could lead to Regular Expression Denial-of-Service (ReDoS) vulnerabilities if the input is controlled by an attacker. Consider using hardcoded regexes or performing input validation to mitigate this risk.

- new RegExp(`\\${delegateModelNames.join('|')}(Unchecked)?(Create|Update).*Input`)
+ // Consider replacing with hardcoded regexes or validating `delegateModelNames` to ensure they do not form a vulnerable regex pattern.

Also applies to: 352-354

Comment on lines 281 to 325
});
}

/**
* Gets the foreign key fields of the given relation field.
*/
export function getForeignKeyFields(relationField: DataModelField) {
if (!isRelationshipField(relationField)) {
return [];
}

const relAttr = relationField.attributes.find((attr) => attr.decl.ref?.name === '@relation');
if (relAttr) {
// find "fields" arg
const fieldsArg = getAttributeArg(relAttr, 'fields');
if (fieldsArg && isArrayExpr(fieldsArg)) {
return fieldsArg.items
.filter((item): item is ReferenceExpr => isReferenceExpr(item))
.map((item) => item.target.ref as DataModelField);
}
}

return [];
}

/**
* Gets the relation field of the given foreign key field.
*/
export function getRelationField(fkField: DataModelField) {
const model = fkField.$container as DataModel;
return model.fields.find((f) => {
const relAttr = f.attributes.find((attr) => attr.decl.ref?.name === '@relation');
if (relAttr) {
const fieldsArg = getAttributeArg(relAttr, 'fields');
if (fieldsArg && isArrayExpr(fieldsArg)) {
return fieldsArg.items.some((item) => isReferenceExpr(item) && item.target.ref === fkField);
}
}
return false;
});
}

export function resolvePath(_path: string, options: Pick<PluginOptions, 'schemaPath'>) {
if (path.isAbsolute(_path)) {
return _path;
Copy link
Contributor

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 no overlapping diff hunk was found. Original lines [327-327]

The resolvePath function uses user input in a path.resolve call, which could potentially lead to a path traversal vulnerability. It's crucial to ensure that any user input is properly sanitized or validated before being used in file path operations to prevent unauthorized access to the file system. Consider implementing input validation or using a safer approach to handle file paths.

- return path.resolve(path.dirname(options.schemaPath), _path);
+ // Ensure _path is sanitized or validated before use
+ return path.resolve(path.dirname(options.schemaPath), sanitizePath(_path));

Comment on lines 121 to 127
getPrismaOnly?: boolean;
enhancements?: EnhancementKind[];
enhanceOptions?: Partial<EnhancementOptions>;
extraSourceFiles?: { name: string; content: string }[];
};

const defaultOptions: SchemaLoadOptions = {
Copy link
Contributor

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 no overlapping diff hunk was found. Original lines [40-40]

The use of execSync with the cmd parameter derived from function arguments raises a potential security concern related to command injection. Ensure that the cmd parameter is either not user-controllable or is properly sanitized to prevent malicious command execution.


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

The use of path.join with potentially user-controllable input in getWorkspaceRoot and getWorkspaceNpmCacheFolder functions could lead to path traversal vulnerabilities. Ensure that any user input is properly sanitized or validated to prevent unauthorized file system access.

Also applies to: 75-75

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