{"_id":"@bluehalo/sof-graphql-invariant","_rev":"8-2fb4271ce7703321c6e2dc4f15eecb5e","name":"@bluehalo/sof-graphql-invariant","dist-tags":{"latest":"2.1.0"},"versions":{"2.0.0":{"name":"@bluehalo/sof-graphql-invariant","version":"2.0.0","author":{"name":"Robert-W","email":"rwinterbottom@asymmetrik.com"},"license":"MIT","_id":"@bluehalo/sof-graphql-invariant@2.0.0","maintainers":[{"name":"ashin-bluehalo","email":"andrew.shin@bluehalo.com"},{"name":"ekoon121","email":"ekoon@asymmetrik.com"},{"name":"reblace","email":"reblace@gmail.com"}],"contributors":[{"name":"Eugene Koon"},{"name":"Luan Tran"}],"homepage":"https://github.com/BlueHalo/node-fhir-server-core","dist":{"shasum":"5d47a5367d2f06cb6d67b675114f69847465c200","tarball":"https://registry.npmjs.org/@bluehalo/sof-graphql-invariant/-/sof-graphql-invariant-2.0.0.tgz","fileCount":17,"integrity":"sha512-TEySFfwCtJyBMFieXuFEslBfLU9YOQepwuM+KP8m7+dgXM1q2bNBxPo7cJS09Q3H4EFAep9Mk2WPSGuLw559ZA==","signatures":[{"sig":"MEYCIQCleIylA7nhR6+JRC4VCDXtZ6WFL0nLRkrhEASWh66JIAIhAKM9oGgn8rRO1GmKk/S+u1Y/4xkrTjWnDcd3ntZV9Acq","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84853},"main":"index.js","gitHead":"717c4ad053a5034563d778318b9ccb673d025930","scripts":{"test":"jest"},"_npmUser":{"name":"ashin-bluehalo","email":"andrew.shin@bluehalo.com"},"repository":{"type":"git","directory":"packages/sof-graphql-invariant"},"_npmVersion":"8.5.0","description":"Smart on FHIR scope checker for GraphQL","directories":{},"_nodeVersion":"16.14.2","dependencies":{"graphql":"^15.6.0","@bluehalo/sof-scope-checker":"^1.0.7"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/sof-graphql-invariant_2.0.0_1708114008280_0.7227475181888254","host":"s3://npm-registry-packages"}},"2.1.0":{"name":"@bluehalo/sof-graphql-invariant","version":"2.1.0","author":{"name":"Robert-W","email":"rwinterbottom@asymmetrik.com"},"license":"MIT","_id":"@bluehalo/sof-graphql-invariant@2.1.0","maintainers":[{"name":"ekdeveloper","email":"eugene.koon@bluehalo.com"},{"name":"shane-bh","email":"shane.oneill@bluehalo.com"},{"name":"ashin-bluehalo","email":"andrew.shin@bluehalo.com"},{"name":"reblace","email":"reblace@gmail.com"}],"contributors":[{"name":"Eugene Koon"},{"name":"Luan Tran"}],"homepage":"https://github.com/Bluehalo/node-fhir-server-core","dist":{"shasum":"9dae63ffc8f417dbe962658723d41bb2c61b9296","tarball":"https://registry.npmjs.org/@bluehalo/sof-graphql-invariant/-/sof-graphql-invariant-2.1.0.tgz","fileCount":6,"integrity":"sha512-xhx5UMZeY9CJa9pKbI6IfXB8wBCmVgvZHYJVDb78sBE9hWady4gKi8zRRktIWhxjGhpINV0OOP1OAaDTJnMVmg==","signatures":[{"sig":"MEYCIQDoWxX7rTHNg/gfloQUiaEXwrFFMB9ZUPZjtq0TMkRMzgIhALiGCSpLnyj0jhlgcjGt+xrOv6ckC+ASxlZVC5gFGh65","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":18123},"main":"index.js","gitHead":"717c4ad053a5034563d778318b9ccb673d025930","scripts":{"test":"jest"},"_npmUser":{"name":"ekdeveloper","email":"eugene.koon@bluehalo.com"},"repository":{"type":"git","directory":"packages/sof-graphql-invariant"},"description":"Smart on FHIR scope checker for GraphQL","directories":{},"dependencies":{"graphql":"^16.9.0","@bluehalo/sof-scope-checker":"^1.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0"},"_npmOperationalInternal":{"tmp":"tmp/sof-graphql-invariant_2.1.0_1726061347354_0.5925205696637161","host":"s3://npm-registry-packages"}}},"time":{"created":"2024-02-16T20:06:48.149Z","modified":"2026-03-25T20:06:12.718Z","2.0.0":"2024-02-16T20:06:48.420Z","2.1.0":"2024-09-11T13:29:07.496Z"},"author":{"name":"Robert-W","email":"rwinterbottom@asymmetrik.com"},"license":"MIT","homepage":"https://github.com/Bluehalo/node-fhir-server-core","repository":{"type":"git","directory":"packages/sof-graphql-invariant"},"description":"Smart on FHIR scope checker for GraphQL","contributors":[{"name":"Eugene Koon"},{"name":"Luan Tran"}],"maintainers":[{"email":"reblace@gmail.com","name":"reblace"},{"email":"eugene.koon@bluehalo.com","name":"ekdeveloper"},{"email":"andrew.shin@bluehalo.com","name":"ashin-bluehalo"},{"email":"shane.oneill@bluehalo.com","name":"shane-bh"},{"email":"rnmercado@gmail.com","name":"rodmercad"}],"readme":"# `SOF-GraphQL-Invariant`\n\n> Utility for validating patient and user level scopes for the SMART on FHIR\n> specification in a GraphQL based server.\n\n# Install\n\n```shell\nyarn add @bluehalo/sof-graphql-invariant\n```\n\n## Usage\n\nIn this example, we will implement this on a single schema, PatientSchema. It\ncan work on queries and mutations. It does have some required arguments so\nplease see [Arguments](#arguments) below for more information. This will reject\nrequests on a resource level instead of across the entire request and will\nreject them in a manner that meets conformance standards for FHIR and GraphQL.\n\n```javascript\nconst scopeInvariant = require('@bluehalo/sof-graphql-invariant');\n\n// NOTE: All the paths for the following modules are fictional, you will need\n// to provide your own path to these resources, these are for example only\n\n// This needs to be of GraphQLInputObjectType type\nconst OperationOutcome = require('./inputs/operationoutcome.input.js');\n// Patient Schema that will be used for returning the patient data\nconst PatientSchema = require('./schemas/patient.schema.js');\n// Patient arguments\nconst PatientArgs = require('./args/patient.parameters.js');\n// Resolver you wish to use for this particular query\nconst patientQueryResolver = require('./patient/resolver.js');\n\n// When defining a query to be used in a Root Schema, use this module\n// as your resolver, it will invoke yours if everything meets the requirements\nconst PatientQuery = {\n  description: 'Patient specific graphql query',\n  type: PatientSchema,\n  args: PatientArgs.\n  resolver: scopeInvariant({\n    schema: OperationOutcome,\n    action: 'read',\n    name: 'Patient',\n  }, patientQueryResolver)\n};\n\n// Now use this in your root graphql schema somewhere\nlet root = new GraphQLObjectType({\n  name: 'Query',\n  description: 'Root query for all resources',\n  fields: { Patient: PatientQuery }\n});\n```\n\nSee [sof-graphql-invariant tests](https://github.com/Bluehalo/node-fhir-server-core/tree/master/packages/sof-graphql-invariant/index.test.js) for more usage examples.\n\n### Environment variables\n\n#### `SOF_AUTHENTICATION`\n\nDisable authentication, it is enabled by default. See [disabling](#disabling).\n\nType: `String`  \nValue: `false`\n\n#### `HAS_GRAPHIQL`\n\nDisable authentication for graphiql only while keeping it on other endpoints. See [Disabling for Graphiql only](#disabling-for-graphiql-only).\n\nType: `String`  \nValue: `true`\n\n### Disabling\n\nIf you use this invariant, it will check scopes on all incoming requests. If you want to disable this or provide a toggle mechanism, you can do so by setting an environment variable. To disable authentication, set `SOF_AUTHENTICATION` to false. It will only disable authentication if this is explicitly set to false.\n\n```javascript\nconst scopeInvariant = require('@bluehalo/sof-graphql-invariant');\n\n// Set the ENV\nprocess.env.SOF_AUTHENTICATION = 'false';\n\n/**\n* NOTE: You *MUST* still provide a valid config if you are using\n* sof-graphql-invariant, even if it is disabled. This is just a mock config and\n* will not work unless you define all variables, see above for a more real world\n* example.\n*/\nconst ExamplePatientQuery = {\n  description: 'PatientQuery'\n  type: PatientSchema,\n  args: PatientArgs,\n  resolver: scopeInvariant({\n    name: 'Patient',\n    action: 'read',\n    schema: OperationOutcomeInputSchema\n  }, patientResolver)\n};\n```\n\n### Disabling for Graphiql only\n\nSometimes it is useful to enable authentication in development but disable it when you are using the graphiql explorer. This requires two things. First is an environment variable stating you are using it, `HAS_GRAPHIQL`. Second, that the endpoint ends with `$graphiql`. If you do this, you can have authentication enabled on your graphql schemas but not if the request is coming from GraphiQL.\n\n```javascript\nconst scopeInvariant = require('@bluehalo/sof-graphql-invariant');\n// Set the ENV\nprocess.env.HAS_GRAPHIQL = 'true';\n\n/**\n* NOTE: You *MUST* still provide a valid config if you are using\n* sof-graphql-invariant, even if it is disabled. This is just a mock config and\n* will not work unless you define all variables, see above for a more real world\n* example.\n*/\nconst ExamplePatientMutation = {\n  description: 'PatientMutation'\n  type: PatientSchema,\n  args: PatientArgs,\n  resolver: scopeInvariant({\n    name: 'Patient',\n    action: 'write',\n    schema: OperationOutcomeInputSchema\n  }, patientResolver)\n};\n```\n\n## Arguments\n\n`@bluehalo/sof-graphql-invariant` exports a single function which takes two arguments. One is a set of options and the other is a resolver function.\n\n### Options\n\nThe first argument we have is an options object, it contains all of the following:\n\n#### `name`\n\nName of the resource as it would appear in SMART on FHIR scopes.\n\nType: `String`  \nRequired: `true`\n\n#### `action`\n\nThe action the user wants to take. Can be `read`, `write`, or `*`.\n\nType: `String`  \nRequired: `true`\n\n#### `schema`\n\nThe GraphQLInputObjectType that represents an OperationOutcome error.\n\nType: `GraphQLInputObjectType`  \nRequired: `true`\n\n### Resolver\n\nThe second argument is the resolver function you want to be invoked after this invariant checker checks the\nuser scopes against the allowed scopes for the action being performed.\n\nType: `Function`  \nRequired: `true`\n","readmeFilename":"README.md"}