diff --git a/README.md b/README.md index e97302496..2a43a8573 100644 --- a/README.md +++ b/README.md @@ -216,11 +216,15 @@ Commit the changes. Create a pull request targeting the main branch. Await PR approval, then merge it into main to integrate new versions. -## 6. Publish to NPM: +## 6. Create a Release: -After merging, trigger the "Publish to NPM" workflow in the Actions tab. +After merging, click on Tags -> Releases -> 'Draft a new release' or visit https://github.com/exogee-technology/graphweaver/releases/new. Choose a new tag for the release, then fill in the description. Populate New Features and tidy up the list of PRs, hit Publish release -## 7. Verify and Monitor: +## 7. Publish to NPM: + +Trigger the "Publish to NPM" workflow in the Actions tab. + +## 8. Verify and Monitor: Monitor the workflow progress in GitHub Actions. Confirm successful publication in the npm registry. diff --git a/src/examples/auth-zero/package.json b/src/examples/auth-zero/package.json index c18cec517..8e9b9ee52 100644 --- a/src/examples/auth-zero/package.json +++ b/src/examples/auth-zero/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver-example-auth-zero", - "version": "2.11.0", + "version": "2.11.1", "license": "Apache-2.0", "private": true, "description": "Example of connecting a SQLite database with Auth0.", diff --git a/src/examples/aws-cognito/package.json b/src/examples/aws-cognito/package.json index 5edc7ddf5..9dcb403cb 100644 --- a/src/examples/aws-cognito/package.json +++ b/src/examples/aws-cognito/package.json @@ -1,7 +1,7 @@ { "name": "@exogee/graphweaver-example-aws-cognito", "private": true, - "version": "2.11.0", + "version": "2.11.1", "license": "Apache-2.0", "description": "Example of connecting to AWS Cognito", "main": "lib/index.js", diff --git a/src/examples/databases/package.json b/src/examples/databases/package.json index 26fc1f83e..a29ea5c72 100644 --- a/src/examples/databases/package.json +++ b/src/examples/databases/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver-example-databases", - "version": "2.11.0", + "version": "2.11.1", "license": "Apache-2.0", "private": true, "description": "Example of connecting a MySQL and PostgreSQL database together.", diff --git a/src/examples/federation/package.json b/src/examples/federation/package.json index 311f78cc0..e5f41c6e9 100644 --- a/src/examples/federation/package.json +++ b/src/examples/federation/package.json @@ -1,7 +1,7 @@ { "name": "@exogee/graphweaver-example-federation", "private": true, - "version": "2.11.0", + "version": "2.11.1", "license": "Apache-2.0", "description": "Example app used to test federation compatibility", "main": "lib/index.js", diff --git a/src/examples/microsoft-entra/package.json b/src/examples/microsoft-entra/package.json index 1ec40520a..1a0086cd1 100644 --- a/src/examples/microsoft-entra/package.json +++ b/src/examples/microsoft-entra/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver-example-microsoft-entra", - "version": "2.11.0", + "version": "2.11.1", "license": "Apache-2.0", "private": true, "description": "Example of connecting a SQLite database with Microsoft Entra.", diff --git a/src/examples/okta/package.json b/src/examples/okta/package.json index c18780188..3da3b7489 100644 --- a/src/examples/okta/package.json +++ b/src/examples/okta/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver-example-okta", - "version": "2.11.0", + "version": "2.11.1", "license": "Apache-2.0", "private": true, "description": "Example of connecting a SQLite database with Okta.", diff --git a/src/examples/rest-with-auth/package.json b/src/examples/rest-with-auth/package.json index 50d49f263..a2e7e6daf 100644 --- a/src/examples/rest-with-auth/package.json +++ b/src/examples/rest-with-auth/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver-example-rest-with-auth", - "version": "2.11.0", + "version": "2.11.1", "license": "Apache-2.0", "private": true, "description": "Example of connecting a Rest API with a MySQL database and complex auth.", diff --git a/src/examples/rest/package.json b/src/examples/rest/package.json index 48d049a8c..562366978 100644 --- a/src/examples/rest/package.json +++ b/src/examples/rest/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver-example-rest", - "version": "2.11.0", + "version": "2.11.1", "license": "Apache-2.0", "description": "Simple example of connecting to a Rest API.", "private": true, diff --git a/src/examples/s3-storage/package.json b/src/examples/s3-storage/package.json index c6cf68b25..62a824ab9 100644 --- a/src/examples/s3-storage/package.json +++ b/src/examples/s3-storage/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver-example-s3-storage", - "version": "2.11.0", + "version": "2.11.1", "license": "Apache-2.0", "private": true, "description": "Example of connecting Graphweaver to an AWS S3 bucket.", diff --git a/src/examples/s3-storage/src/frontend/types.generated.ts b/src/examples/s3-storage/src/frontend/types.generated.ts index 534163e6f..62c6c5870 100644 --- a/src/examples/s3-storage/src/frontend/types.generated.ts +++ b/src/examples/s3-storage/src/frontend/types.generated.ts @@ -91,6 +91,7 @@ export type AdminUiFilterMetadata = { export enum AdminUiFilterType { Boolean = 'BOOLEAN', DateRange = 'DATE_RANGE', + DropDownText = 'DROP_DOWN_TEXT', Enum = 'ENUM', Numeric = 'NUMERIC', Relationship = 'RELATIONSHIP', diff --git a/src/examples/s3-storage/src/types.generated.ts b/src/examples/s3-storage/src/types.generated.ts index 534163e6f..62c6c5870 100644 --- a/src/examples/s3-storage/src/types.generated.ts +++ b/src/examples/s3-storage/src/types.generated.ts @@ -91,6 +91,7 @@ export type AdminUiFilterMetadata = { export enum AdminUiFilterType { Boolean = 'BOOLEAN', DateRange = 'DATE_RANGE', + DropDownText = 'DROP_DOWN_TEXT', Enum = 'ENUM', Numeric = 'NUMERIC', Relationship = 'RELATIONSHIP', diff --git a/src/examples/sqlite/package.json b/src/examples/sqlite/package.json index a15134e04..74b241e72 100644 --- a/src/examples/sqlite/package.json +++ b/src/examples/sqlite/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver-example-sqlite", - "version": "2.11.0", + "version": "2.11.1", "license": "Apache-2.0", "private": true, "description": "Example of connecting a SQLite database.", diff --git a/src/examples/xero/package.json b/src/examples/xero/package.json index a360958a2..433c914f6 100644 --- a/src/examples/xero/package.json +++ b/src/examples/xero/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver-example-xero", - "version": "2.11.0", + "version": "2.11.1", "license": "Apache-2.0", "private": true, "description": "Example of using @exogee/graphweaver to connect two Xero instances", diff --git a/src/examples/xero/src/frontend/types.generated.ts b/src/examples/xero/src/frontend/types.generated.ts index 2727246f8..5c20e56e0 100644 --- a/src/examples/xero/src/frontend/types.generated.ts +++ b/src/examples/xero/src/frontend/types.generated.ts @@ -223,6 +223,7 @@ export type AdminUiFilterMetadata = { export enum AdminUiFilterType { Boolean = 'BOOLEAN', DateRange = 'DATE_RANGE', + DropDownText = 'DROP_DOWN_TEXT', Enum = 'ENUM', Numeric = 'NUMERIC', Relationship = 'RELATIONSHIP', diff --git a/src/examples/xero/src/types.generated.ts b/src/examples/xero/src/types.generated.ts index 2727246f8..5c20e56e0 100644 --- a/src/examples/xero/src/types.generated.ts +++ b/src/examples/xero/src/types.generated.ts @@ -223,6 +223,7 @@ export type AdminUiFilterMetadata = { export enum AdminUiFilterType { Boolean = 'BOOLEAN', DateRange = 'DATE_RANGE', + DropDownText = 'DROP_DOWN_TEXT', Enum = 'ENUM', Numeric = 'NUMERIC', Relationship = 'RELATIONSHIP', diff --git a/src/packages/admin-ui-components/package.json b/src/packages/admin-ui-components/package.json index 6c9511df6..ad6050800 100644 --- a/src/packages/admin-ui-components/package.json +++ b/src/packages/admin-ui-components/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver-admin-ui-components", - "version": "2.11.0", + "version": "2.11.1", "description": "Components from Graphweaver's admin UI which you can use in your projects as you like", "license": "Apache-2.0", "type": "module", diff --git a/src/packages/admin-ui/package.json b/src/packages/admin-ui/package.json index 2e8bf56a2..2cb86f32f 100644 --- a/src/packages/admin-ui/package.json +++ b/src/packages/admin-ui/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver-admin-ui", - "version": "2.11.0", + "version": "2.11.1", "type": "module", "main": "dist/main.js", "types": "src/main.tsx", diff --git a/src/packages/apollo-client/package.json b/src/packages/apollo-client/package.json index 75b75ffda..fc771c40e 100644 --- a/src/packages/apollo-client/package.json +++ b/src/packages/apollo-client/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver-apollo-client", - "version": "2.11.0", + "version": "2.11.1", "description": "Useful helpers for working with Apollo Client and Graphweaver", "license": "Apache-2.0", "type": "module", diff --git a/src/packages/auth-ui-components/package.json b/src/packages/auth-ui-components/package.json index b9bc2dbe8..6dfb5f346 100644 --- a/src/packages/auth-ui-components/package.json +++ b/src/packages/auth-ui-components/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver-auth-ui-components", - "version": "2.11.0", + "version": "2.11.1", "description": "Components from Graphweaver's Auth UI which you can use in your projects as you like", "license": "Apache-2.0", "type": "module", diff --git a/src/packages/auth/package.json b/src/packages/auth/package.json index ba9f25ceb..fc09d3cdb 100644 --- a/src/packages/auth/package.json +++ b/src/packages/auth/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver-auth", - "version": "2.11.0", + "version": "2.11.1", "description": "Row-Level Security support for @exogee/graphweaver", "license": "Apache-2.0", "scripts": { diff --git a/src/packages/auth/src/auth-utils.ts b/src/packages/auth/src/auth-utils.ts index 036ae4f8e..325b3586c 100644 --- a/src/packages/auth/src/auth-utils.ts +++ b/src/packages/auth/src/auth-utils.ts @@ -181,7 +181,8 @@ export const assertObjectLevelPermissions = async ( entityName: string, id: string | number, - accessType: AccessType + accessType: AccessType, + transactional: boolean ) { const acl = getACL(entityName); const accessControlEntry = buildAccessControlEntryForUser( @@ -222,6 +223,19 @@ export async function checkEntityPermission( _and: [{ [primaryKeyField]: id }, accessFilter], }; + // If we've made it down here, we need to assert that this is all happening within a transaction + // or it's possible we'll do a partial write before we discover they were trying to do something + // they shouldn't be allowed to do. + // + // We don't want this check higher up, because it should only be applied if they've actually configured + // row level security ACLs. + if (!transactional) { + logger.error( + 'Row Level Security can only be applied within a transaction and this hook is not transactional.' + ); + throw new Error(GENERIC_AUTH_ERROR_MESSAGE); + } + try { const { provider } = graphweaverMetadata.getEntityByName(entityName) ?? {}; if (!provider) { @@ -249,7 +263,8 @@ export async function checkAuthorization( entityName: string, id: string | number, requestInput: Partial, - requiredPermission: AccessType + requiredPermission: AccessType, + transactional: boolean ) { logger.trace({ entityName, id, requestInput, requiredPermission }, 'Entering checkAuthorization'); @@ -266,7 +281,7 @@ export async function checkAuthorization( logger.trace('They can, now checking entity permissions.'); // Now check whether the root entity passes permissions filters (if set) - await checkEntityPermission(entityName, id, requiredPermission); + await checkEntityPermission(entityName, id, requiredPermission, transactional); // Recurse through the list const relatedEntityAuthChecks: Promise[] = []; @@ -296,7 +311,13 @@ export async function checkAuthorization( // The creation hook will triggered for that entity and the permissions checked if (relatedId) { relatedEntityAuthChecks.push( - checkAuthorization(relatedEntityMetadata.name, relatedId, item, accessType) + checkAuthorization( + relatedEntityMetadata.name, + relatedId, + item, + accessType, + transactional + ) ); } } diff --git a/src/packages/auth/src/decorators/hooks/acl.ts b/src/packages/auth/src/decorators/hooks/acl.ts index 11b484ec5..494a2aea3 100644 --- a/src/packages/auth/src/decorators/hooks/acl.ts +++ b/src/packages/auth/src/decorators/hooks/acl.ts @@ -462,9 +462,7 @@ export const afterCreateOrUpdate = ( const items = params.args.items; const entities = (params.entities ?? []) as G[]; - // 1. Check to ensure we are within a transaction - assertTransactional(params.transactional); - // 2. Check user has permission for each for each entity + // Check user has permission for each for each entity, recursing as we go. const authChecks = entities.map((entity, index) => entity?.[primaryKeyField] ? checkAuthorization( @@ -473,7 +471,8 @@ export const afterCreateOrUpdate = ( ? Number(entity[primaryKeyField]) : String(entity[primaryKeyField]), items[index], - accessType + accessType, + params.transactional ) : undefined ); diff --git a/src/packages/aws-cognito/package.json b/src/packages/aws-cognito/package.json index 3b11ec7dd..1f1dfc8d7 100644 --- a/src/packages/aws-cognito/package.json +++ b/src/packages/aws-cognito/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver-aws", - "version": "2.11.0", + "version": "2.11.1", "main": "lib/index.js", "source": "src/index.ts", "directories": { diff --git a/src/packages/builder/package.json b/src/packages/builder/package.json index 6eb914938..100e4cc96 100644 --- a/src/packages/builder/package.json +++ b/src/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver-builder", - "version": "2.11.0", + "version": "2.11.1", "description": "A tool for building and running Graphweaver projects", "license": "Apache-2.0", "scripts": { diff --git a/src/packages/cdk/package.json b/src/packages/cdk/package.json index 4586e6c90..cd766e7f1 100644 --- a/src/packages/cdk/package.json +++ b/src/packages/cdk/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver-cdk", - "version": "2.11.0", + "version": "2.11.1", "description": "Deploy Graphweaver to AWS", "license": "Apache-2.0", "directories": { diff --git a/src/packages/cli/package.json b/src/packages/cli/package.json index 28ebc8d28..f4e21d53f 100644 --- a/src/packages/cli/package.json +++ b/src/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "graphweaver", - "version": "2.11.0", + "version": "2.11.1", "description": "A tool for managing, running, debugging and building Graphweaver projects", "license": "Apache-2.0", "scripts": { diff --git a/src/packages/config/package.json b/src/packages/config/package.json index 835f560e1..7e8635d50 100644 --- a/src/packages/config/package.json +++ b/src/packages/config/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver-config", - "version": "2.11.0", + "version": "2.11.1", "description": "Retrieve and parse Graphweaver configurations", "license": "Apache-2.0", "scripts": { diff --git a/src/packages/core/package.json b/src/packages/core/package.json index 20bcc2d58..386810c35 100644 --- a/src/packages/core/package.json +++ b/src/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver", - "version": "2.11.0", + "version": "2.11.1", "description": "Graphweaver Core Package", "license": "Apache-2.0", "scripts": { diff --git a/src/packages/end-to-end/package.json b/src/packages/end-to-end/package.json index d200c43ef..65c9417b1 100644 --- a/src/packages/end-to-end/package.json +++ b/src/packages/end-to-end/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver-end-to-end", - "version": "2.11.0", + "version": "2.11.1", "description": "Graphweaver Test Suite", "license": "Apache-2.0", "scripts": { diff --git a/src/packages/load-testing/package.json b/src/packages/load-testing/package.json index efdb377ef..00db96638 100644 --- a/src/packages/load-testing/package.json +++ b/src/packages/load-testing/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver-load-testing", - "version": "2.11.0", + "version": "2.11.1", "private": true, "description": "Graphweaver Load Testing Suite", "license": "Apache-2.0", diff --git a/src/packages/logger/package.json b/src/packages/logger/package.json index 331d2fa9a..001cc49bc 100644 --- a/src/packages/logger/package.json +++ b/src/packages/logger/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/logger", - "version": "2.11.0", + "version": "2.11.1", "description": "Common logging output for Exogee projects", "license": "Apache-2.0", "directories": { diff --git a/src/packages/mikro-orm-sqlite-wasm/package.json b/src/packages/mikro-orm-sqlite-wasm/package.json index 7faf3f2ef..3badd43e7 100644 --- a/src/packages/mikro-orm-sqlite-wasm/package.json +++ b/src/packages/mikro-orm-sqlite-wasm/package.json @@ -1,6 +1,6 @@ { "name": "mikro-orm-sqlite-wasm", - "version": "2.11.0", + "version": "2.11.1", "description": "MikroORM SQLite Driver Wasm", "license": "Apache-2.0", "scripts": { diff --git a/src/packages/mikroorm/package.json b/src/packages/mikroorm/package.json index 5c3464e5f..32c367203 100644 --- a/src/packages/mikroorm/package.json +++ b/src/packages/mikroorm/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver-mikroorm", - "version": "2.11.0", + "version": "2.11.1", "description": "MikroORM backend for @exogee/graphweaver", "license": "Apache-2.0", "scripts": { diff --git a/src/packages/rest-legacy/package.json b/src/packages/rest-legacy/package.json index 4b449e652..6abe789d9 100644 --- a/src/packages/rest-legacy/package.json +++ b/src/packages/rest-legacy/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver-rest-legacy", - "version": "2.11.0", + "version": "2.11.1", "description": "Legacy RESTful backend adapter for @exogee/graphweaver", "license": "Apache-2.0", "scripts": { diff --git a/src/packages/rest/package.json b/src/packages/rest/package.json index 4672f6578..6c76747e4 100644 --- a/src/packages/rest/package.json +++ b/src/packages/rest/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver-rest", - "version": "2.11.0", + "version": "2.11.1", "description": "RESTful backend adapter for @exogee/graphweaver", "license": "Apache-2.0", "scripts": { diff --git a/src/packages/scalars/package.json b/src/packages/scalars/package.json index 1e1f6e280..6228e1681 100644 --- a/src/packages/scalars/package.json +++ b/src/packages/scalars/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver-scalars", - "version": "2.11.0", + "version": "2.11.1", "description": "Common scalar types for use with @exogee/graphweaver", "license": "Apache-2.0", "main": "lib/index.js", diff --git a/src/packages/server/package.json b/src/packages/server/package.json index 8596c1527..cf515e51a 100644 --- a/src/packages/server/package.json +++ b/src/packages/server/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver-server", - "version": "2.11.0", + "version": "2.11.1", "description": "Server support for @exogee/graphweaver", "license": "Apache-2.0", "scripts": { diff --git a/src/packages/storage-provider/package.json b/src/packages/storage-provider/package.json index 43a08e147..5aeb23b9d 100644 --- a/src/packages/storage-provider/package.json +++ b/src/packages/storage-provider/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver-storage-provider", - "version": "2.11.0", + "version": "2.11.1", "description": "Graphweaver Storage Provider Package", "license": "Apache-2.0", "scripts": { diff --git a/src/packages/vite-plugin-graphweaver/package.json b/src/packages/vite-plugin-graphweaver/package.json index 7507ae265..762a64c3e 100644 --- a/src/packages/vite-plugin-graphweaver/package.json +++ b/src/packages/vite-plugin-graphweaver/package.json @@ -1,6 +1,6 @@ { "name": "vite-plugin-graphweaver", - "version": "2.11.0", + "version": "2.11.1", "description": "A vite plugin for use with @exogee/graphweaver's admin UI", "license": "Apache-2.0", "main": "lib/index.js", diff --git a/src/packages/xero/package.json b/src/packages/xero/package.json index 3a526b727..1efeefeb3 100644 --- a/src/packages/xero/package.json +++ b/src/packages/xero/package.json @@ -1,6 +1,6 @@ { "name": "@exogee/graphweaver-xero", - "version": "2.11.0", + "version": "2.11.1", "description": "Xero backend for @exogee/graphweaver", "license": "Apache-2.0", "scripts": {