From 4b5747c7308f49733103aae5bc5af4b3e9955394 Mon Sep 17 00:00:00 2001 From: Damodar Lohani Date: Sun, 4 Sep 2022 06:52:15 +0545 Subject: [PATCH 1/9] mock headers endpoint --- app/controllers/mock.php | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/app/controllers/mock.php b/app/controllers/mock.php index d3b150a55f..ec02c368da 100644 --- a/app/controllers/mock.php +++ b/app/controllers/mock.php @@ -194,6 +194,35 @@ App::delete('/v1/mock/tests/bar') ->action(function ($required, $default, $z) { }); +/** Endpoint to test if required headers are sent from the SDK */ +App::get('/v1/mock/tests/general/headers') + ->desc('Get headers') + ->groups(['mock']) + ->label('scope', 'public') + ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT]) + ->label('sdk.namespace', 'general') + ->label('sdk.method', 'headers') + ->label('sdk.description', 'Return headers from the request') + ->label('sdk.response.code', Response::STATUS_CODE_OK) + ->label('sdk.response.model', Response::MODEL_MOCK) + ->label('sdk.mock', true) + ->inject('request') + ->inject('response') + ->action(function (Request $request, Response $response) { + $res = [ + 'x-sdk-name' => $request->getHeader('x-sdk-name'), + 'x-sdk-platform' => $request->getHeader('x-sdk-platform'), + 'x-sdk-language' => $request->getHeader('x-sdk-language'), + 'x-sdk-version' => $request->getHeader('x-sdk-version'), + ]; + $res = array_map(function ($key, $value) { + return $key . ': ' . $value; + }, array_keys($res), $res); + $res = implode("; ", $res); + + $response->dynamic(new Document(['result' => $res]), Response::MODEL_MOCK); + }); + App::get('/v1/mock/tests/general/download') ->desc('Download File') ->groups(['mock']) From 3b39b3a88d0e7580d0429d08c1fdde367c0ec00f Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Wed, 14 Sep 2022 18:46:35 +0530 Subject: [PATCH 2/9] feat: update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index aeb3f97d92..35e9075a65 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ English | [简体中文](README-CN.md) -[**Appwrite 0.15 has been released! Learn what's new!**](https://dev.to/appwrite/announcing-appwrite-015-with-phone-authentication-more-5cjj) +[**Appwrite 1.0 has been released! Learn what's new!**](https://appwrite.io/1.0) Appwrite is an end-to-end backend server for Web, Mobile, Native, or Backend apps packaged as a set of Docker microservices. Appwrite abstracts the complexity and repetitiveness required to build a modern backend API from scratch and allows you to build secure apps faster. From fab87c7f005974712fc09bb185b7c78eb0de756e Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Wed, 14 Sep 2022 19:40:03 +0200 Subject: [PATCH 3/9] fix: migration for abuse time column --- src/Appwrite/Migration/Version/V15.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Appwrite/Migration/Version/V15.php b/src/Appwrite/Migration/Version/V15.php index aa52bf70dd..6c7e59228f 100644 --- a/src/Appwrite/Migration/Version/V15.php +++ b/src/Appwrite/Migration/Version/V15.php @@ -491,6 +491,7 @@ class V15 extends Migration $this->createPermissionsColumn($id); $this->migrateDateTimeAttribute($id, '_createdAt'); $this->migrateDateTimeAttribute($id, '_updatedAt'); + $this->migrateDateTimeAttribute($id, 'time'); break; case 'attributes': From 5fb6d2fa6ac5bc6beabeefb4b6a33100fd4bb273 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Wed, 14 Sep 2022 19:48:56 +0200 Subject: [PATCH 4/9] chore: add changelog --- CHANGES.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 34bb192984..68ca4abd17 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,8 @@ +# Version 1.0.1 +## Bugs +- Fixed migration for abuse by migrating the `time` attribute [3839](https://github.com/appwrite/appwrite/pull/3839) + +# Version 1.0.0 ## BREAKING CHANGES - All Date values are now stored as ISO-8601 instead of UNIX timestamps [#3516](https://github.com/appwrite/appwrite/pull/3516) - Permission levels and syntax have been reworked. See the Permissions V2 section in the document for more information [#3700](https://github.com/appwrite/appwrite/pull/3700) From 95d322dc3609feb1a1bd5e98557a4b3788b883ad Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Wed, 14 Sep 2022 21:03:00 +0200 Subject: [PATCH 5/9] feat: prepare 1.0.1 release --- .github/ISSUE_TEMPLATE/bug.yaml | 2 +- app/init.php | 2 +- src/Appwrite/Migration/Migration.php | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug.yaml b/.github/ISSUE_TEMPLATE/bug.yaml index 48312828b1..dbd8239d5b 100644 --- a/.github/ISSUE_TEMPLATE/bug.yaml +++ b/.github/ISSUE_TEMPLATE/bug.yaml @@ -37,7 +37,7 @@ body: label: "🎲 Appwrite version" description: "What version of Appwrite are you running?" options: - - Version 1.0.0-RC1 + - Version 1.0.x - Version 0.15.x - Version 0.14.x - Version 0.13.x diff --git a/app/init.php b/app/init.php index 5cdcc82dd0..3c9f785f9d 100644 --- a/app/init.php +++ b/app/init.php @@ -95,7 +95,7 @@ const APP_LIMIT_WRITE_RATE_PERIOD_DEFAULT = 60; // Default maximum write rate pe const APP_KEY_ACCCESS = 24 * 60 * 60; // 24 hours const APP_CACHE_UPDATE = 24 * 60 * 60; // 24 hours const APP_CACHE_BUSTER = 500; -const APP_VERSION_STABLE = '1.0.0'; +const APP_VERSION_STABLE = '1.0.1'; const APP_DATABASE_ATTRIBUTE_EMAIL = 'email'; const APP_DATABASE_ATTRIBUTE_ENUM = 'enum'; const APP_DATABASE_ATTRIBUTE_IP = 'ip'; diff --git a/src/Appwrite/Migration/Migration.php b/src/Appwrite/Migration/Migration.php index a17a962471..c35f5c5df3 100644 --- a/src/Appwrite/Migration/Migration.php +++ b/src/Appwrite/Migration/Migration.php @@ -42,7 +42,8 @@ abstract class Migration */ public static array $versions = [ '1.0.0-RC1' => 'V15', - '1.0.0' => 'V15' + '1.0.0' => 'V15', + '1.0.1' => 'V15', ]; /** From 6c9e805682eefb0d406b6413956429019c6c838a Mon Sep 17 00:00:00 2001 From: Steven <1477010+stnguyen90@users.noreply.github.com> Date: Wed, 14 Sep 2022 12:18:33 -0700 Subject: [PATCH 6/9] Change role:all to any in docs --- docs/sdks/cli/GETTING_STARTED.md | 2 +- docs/sdks/dart/EXAMPLES.md | 23 ++++++++++----------- docs/sdks/flutter-dev/EXAMPLES.md | 34 +++++++++++++++++++------------ docs/sdks/flutter/EXAMPLES.md | 26 +++++++++++------------ docs/services/databases.md | 2 +- docs/services/storage.md | 2 +- 6 files changed, 48 insertions(+), 41 deletions(-) diff --git a/docs/sdks/cli/GETTING_STARTED.md b/docs/sdks/cli/GETTING_STARTED.md index 4d0f6fcba7..564fb4d5f9 100644 --- a/docs/sdks/cli/GETTING_STARTED.md +++ b/docs/sdks/cli/GETTING_STARTED.md @@ -98,7 +98,7 @@ $ appwrite users list To create a document you can use the following command ```sh -$ appwrite database createDocument --collectionId --documentId 'unique()' --data '{ "Name": "Iron Man" }' --read role:all team:abc +$ appwrite database createDocument --collectionId --documentId 'unique()' --data '{ "Name": "Iron Man" }' --permissions 'read("any")' 'read("team:abc")' ``` ### Some Gotchas diff --git a/docs/sdks/dart/EXAMPLES.md b/docs/sdks/dart/EXAMPLES.md index a16ba88385..208cc7f782 100644 --- a/docs/sdks/dart/EXAMPLES.md +++ b/docs/sdks/dart/EXAMPLES.md @@ -3,14 +3,13 @@ Init your Appwrite client: ```dart - Client client = Client(); - - client - .setEndpoint('https://localhost/v1') // Your Appwrite Endpoint - .setProject('5e8cf4f46b5e8') // Your project ID - .setSelfSigned() // Remove in production - ; +Client client = Client(); +client + .setEndpoint('https://localhost/v1') // Your Appwrite Endpoint + .setProject('5e8cf4f46b5e8') // Your project ID + .setSelfSigned() // Remove in production +; ``` Create a new user: @@ -18,12 +17,11 @@ Create a new user: ```dart Users users = Users(client); -Response result = await users.create( +User result = await users.create( userId: '[USER_ID]', email: 'email@example.com', password: 'password', ); - ``` Fetch user profile: @@ -31,7 +29,7 @@ Fetch user profile: ```dart Users users = Users(client); -Response profile = await users.get( +User profile = await users.get( userId: '[USER_ID]', ); ``` @@ -47,8 +45,9 @@ storage.createFile( bucketId: '[BUCKET_ID]', fileId: '[FILE_ID]', // use 'unique()' to automatically generate a unique ID file: file, - read: ['role:all'], - write: [] + permissions: [ + Permission.read(Role.any()), + ], ) .then((response) { print(response); // File uploaded! diff --git a/docs/sdks/flutter-dev/EXAMPLES.md b/docs/sdks/flutter-dev/EXAMPLES.md index ea92ec6e8e..23b631900f 100644 --- a/docs/sdks/flutter-dev/EXAMPLES.md +++ b/docs/sdks/flutter-dev/EXAMPLES.md @@ -3,14 +3,13 @@ Init your Appwrite client: ```dart - Client client = Client(); - - client - .setEndpoint('https://localhost/v1') // Your Appwrite Endpoint - .setProject('5e8cf4f46b5e8') // Your project ID - .setSelfSigned() // Remove in production - ; +Client client = Client(); +client + .setEndpoint('https://localhost/v1') // Your Appwrite Endpoint + .setProject('5e8cf4f46b5e8') // Your project ID + .setSelfSigned() // Remove in production +; ``` Create a new user and session: @@ -18,9 +17,9 @@ Create a new user and session: ```dart Account account = Account(client); -Response user = await account.create(email: 'me@appwrite.io', password: 'password', name: 'My Name'); +final user = await account.create(userId: '[USER_ID]', email: 'me@appwrite.io', password: 'password', name: 'My Name'); -Response session = await account.createSession(email: 'me@appwrite.io', password: 'password'); +final session = await account.createEmailSession(email: 'me@appwrite.io', password: 'password'); ``` @@ -29,7 +28,7 @@ Fetch user profile: ```dart Account account = Account(client); -Response profile = await account.get(); +final profile = await account.get(); ``` Upload File: @@ -37,12 +36,21 @@ Upload File: ```dart Storage storage = Storage(client); -MultipartFile file = MultipartFile.fromFile('./path-to-file/image.jpg', filename: 'image.jpg'); +late InputFile file; + +if(kIsWeb) { + file = InputFile(bytes: pickedFile.bytes, filename: 'image.jpg'); +} else { + file = InputFile(path: './path-to-file/image.jpg', filename: 'image.jpg'); +} storage.createFile( + bucketId: '[BUCKET_ID]', + fileId: '[FILE_ID]', // use 'unique()' to automatically generate a unique ID file: file, - read: ['role:all'], - write: [] + permissions: [ + Permission.read(Role.any()), + ], ) .then((response) { print(response); // File uploaded! diff --git a/docs/sdks/flutter/EXAMPLES.md b/docs/sdks/flutter/EXAMPLES.md index c20544439a..23b631900f 100644 --- a/docs/sdks/flutter/EXAMPLES.md +++ b/docs/sdks/flutter/EXAMPLES.md @@ -3,14 +3,13 @@ Init your Appwrite client: ```dart - Client client = Client(); - - client - .setEndpoint('https://localhost/v1') // Your Appwrite Endpoint - .setProject('5e8cf4f46b5e8') // Your project ID - .setSelfSigned() // Remove in production - ; +Client client = Client(); +client + .setEndpoint('https://localhost/v1') // Your Appwrite Endpoint + .setProject('5e8cf4f46b5e8') // Your project ID + .setSelfSigned() // Remove in production +; ``` Create a new user and session: @@ -18,9 +17,9 @@ Create a new user and session: ```dart Account account = Account(client); -Response user = await account.create(userId: '[USER_ID]', email: 'me@appwrite.io', password: 'password', name: 'My Name'); +final user = await account.create(userId: '[USER_ID]', email: 'me@appwrite.io', password: 'password', name: 'My Name'); -Response session = await account.createSession(email: 'me@appwrite.io', password: 'password'); +final session = await account.createEmailSession(email: 'me@appwrite.io', password: 'password'); ``` @@ -29,7 +28,7 @@ Fetch user profile: ```dart Account account = Account(client); -Response profile = await account.get(); +final profile = await account.get(); ``` Upload File: @@ -40,7 +39,7 @@ Storage storage = Storage(client); late InputFile file; if(kIsWeb) { - file = InputFile(file: await MultipartFile.fromFile('file', './path-to-file/image.jpg', filename: 'image.jpg')); + file = InputFile(bytes: pickedFile.bytes, filename: 'image.jpg'); } else { file = InputFile(path: './path-to-file/image.jpg', filename: 'image.jpg'); } @@ -49,8 +48,9 @@ storage.createFile( bucketId: '[BUCKET_ID]', fileId: '[FILE_ID]', // use 'unique()' to automatically generate a unique ID file: file, - read: ['role:all'], - write: [] + permissions: [ + Permission.read(Role.any()), + ], ) .then((response) { print(response); // File uploaded! diff --git a/docs/services/databases.md b/docs/services/databases.md index 00076dc8da..0e32fa6c77 100644 --- a/docs/services/databases.md +++ b/docs/services/databases.md @@ -4,4 +4,4 @@ All data returned by the Databases service are represented as structured JSON do The Databases service can contain multiple databases, each database can contain multiple collections. A collection is a group of similarly structured documents. The accepted structure of documents is defined by [collection attributes](/docs/databases#attributes). The collection attributes help you ensure all your user-submitted data is validated and stored according to the collection structure. -Using Appwrite permissions architecture, you can assign read or write access to each collection or document in your project for either a specific user, team, user role, or even grant it with public access (`role:all`). You can learn more about [how Appwrite handles permissions and access control](/docs/permissions). \ No newline at end of file +Using Appwrite permissions architecture, you can assign read or write access to each collection or document in your project for either a specific user, team, user role, or even grant it with public access (`any`). You can learn more about [how Appwrite handles permissions and access control](/docs/permissions). \ No newline at end of file diff --git a/docs/services/storage.md b/docs/services/storage.md index 54df77891c..0665128a76 100644 --- a/docs/services/storage.md +++ b/docs/services/storage.md @@ -2,7 +2,7 @@ The Storage service allows you to manage your project files. Using the Storage s Files are managed using buckets. Storage buckets are similar to Collections we have in our [Databases](/docs/databases) service. The difference is, buckets also provide more power to decide what kinds of files, what sizes you want to allow in that bucket, whether or not to encrypt the files, scan with antivirus and more. -Using Appwrite permissions architecture, you can assign read or write access to each bucket or file in your project for either a specific user, team, user role, or even grant it with public access (`role:all`). You can learn more about [how Appwrite handles permissions and access control](/docs/permissions). +Using Appwrite permissions architecture, you can assign read or write access to each bucket or file in your project for either a specific user, team, user role, or even grant it with public access (`any`). You can learn more about [how Appwrite handles permissions and access control](/docs/permissions). The preview endpoint allows you to generate preview images for your files. Using the preview endpoint, you can also manipulate the resulting image so that it will fit perfectly inside your app in terms of dimensions, file size, and style. The preview endpoint also allows you to change the resulting image file format for better compression or image quality for better delivery over the network. From ed79d4dffb8de8c3348d479bf0c618e50bdc2be4 Mon Sep 17 00:00:00 2001 From: Torsten Dittmann Date: Wed, 14 Sep 2022 22:08:44 +0200 Subject: [PATCH 7/9] chore: update readme for 1.0.0 --- README-CN.md | 6 +++--- README.md | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README-CN.md b/README-CN.md index 5d94505dfe..82908f1425 100644 --- a/README-CN.md +++ b/README-CN.md @@ -59,7 +59,7 @@ docker run -it --rm \ --volume /var/run/docker.sock:/var/run/docker.sock \ --volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \ --entrypoint="install" \ - appwrite/appwrite:0.15.3 + appwrite/appwrite:1.0.1 ``` ### Windows @@ -71,7 +71,7 @@ docker run -it --rm ^ --volume //var/run/docker.sock:/var/run/docker.sock ^ --volume "%cd%"/appwrite:/usr/src/code/appwrite:rw ^ --entrypoint="install" ^ - appwrite/appwrite:0.15.3 + appwrite/appwrite:1.0.1 ``` #### PowerShell @@ -81,7 +81,7 @@ docker run -it --rm , --volume /var/run/docker.sock:/var/run/docker.sock , --volume ${pwd}/appwrite:/usr/src/code/appwrite:rw , --entrypoint="install" , - appwrite/appwrite:0.15.3 + appwrite/appwrite:1.0.1 ``` 运行后,可以在浏览器上访问 http://localhost 找到 Appwrite 控制台。在非 Linux 的本机主机上完成安装后,服务器可能需要几分钟才能启动。 diff --git a/README.md b/README.md index 35e9075a65..b9a895bc6e 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,7 @@ docker run -it --rm \ --volume /var/run/docker.sock:/var/run/docker.sock \ --volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \ --entrypoint="install" \ - appwrite/appwrite:0.15.3 + appwrite/appwrite:1.0.1 ``` ### Windows @@ -77,7 +77,7 @@ docker run -it --rm ^ --volume //var/run/docker.sock:/var/run/docker.sock ^ --volume "%cd%"/appwrite:/usr/src/code/appwrite:rw ^ --entrypoint="install" ^ - appwrite/appwrite:0.15.3 + appwrite/appwrite:1.0.1 ``` #### PowerShell @@ -87,7 +87,7 @@ docker run -it --rm , --volume /var/run/docker.sock:/var/run/docker.sock , --volume ${pwd}/appwrite:/usr/src/code/appwrite:rw , --entrypoint="install" , - appwrite/appwrite:0.15.3 + appwrite/appwrite:1.0.1 ``` Once the Docker installation completes, go to http://localhost to access the Appwrite console from your browser. Please note that on non-Linux native hosts, the server might take a few minutes to start after installation completes. From ef4ffcf3a216496a7eb100a2b396e25b3c5b9353 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Tue, 20 Sep 2022 22:03:13 +1200 Subject: [PATCH 8/9] Clear existing permissions for a role on keydown --- app/views/console/comps/permissions-matrix.phtml | 1 + public/dist/scripts/app-all.js | 2 +- public/dist/scripts/app.js | 2 +- public/scripts/permissions-matrix.js | 8 ++++++++ 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/app/views/console/comps/permissions-matrix.phtml b/app/views/console/comps/permissions-matrix.phtml index 836b0843ad..80a424fc46 100644 --- a/app/views/console/comps/permissions-matrix.phtml +++ b/app/views/console/comps/permissions-matrix.phtml @@ -81,6 +81,7 @@ $escapedPermissions = \array_map(function ($perm) { list="types" type="text" x-model="permission.role" + @keydown="clearPermission(index)" @keyup="updatePermission(index)"/> diff --git a/public/dist/scripts/app-all.js b/public/dist/scripts/app-all.js index 11b2bcdfdf..4ebaa92ba3 100644 --- a/public/dist/scripts/app-all.js +++ b/public/dist/scripts/app-all.js @@ -4013,7 +4013,7 @@ this.rawPermissions=permissions;permissions.map(p=>{let{type,role}=this.parsePer if(existing===undefined){let newPermission={role,create:false,read:false,update:false,xdelete:false,};newPermission[type]=true;this.permissions.push(newPermission);} if(index!==-1){existing[type]=true;this.permissions[index]=existing;}});},addPermission(formId){if(this.permissions.length>0&&!this.validate(formId,this.permissions.length-1)){return;} this.permissions.push({role:'',create:false,read:false,update:false,xdelete:false,});},updatePermission(index){setTimeout(()=>{const permission=this.permissions[index];Object.keys(permission).forEach(key=>{if(key==='role'){return;} -const parsedKey=this.parseOutputPermission(key);const permissionString=this.buildPermission(parsedKey,permission.role);if(permission[key]){if(!this.rawPermissions.includes(permissionString)){this.rawPermissions.push(permissionString);}}else{this.rawPermissions=this.rawPermissions.filter(p=>{return!p.includes(permissionString);});}});});},removePermission(index){let row=this.permissions.splice(index,1);if(row.length===1){this.rawPermissions=this.rawPermissions.filter(p=>!p.includes(row[0].role));}},parsePermission(permission){let parts=permission.split('(');let type=parts[0];let role=parts[1].replace(')','').replace(' ','').replaceAll('"','');return{type,role};},buildPermission(type,role){return`${type}("${role}")`},parseInputPermission(key){if(key==='delete'){return'xdelete';} +const parsedKey=this.parseOutputPermission(key);const permissionString=this.buildPermission(parsedKey,permission.role);if(permission[key]){if(!this.rawPermissions.includes(permissionString)){this.rawPermissions.push(permissionString);}}else{this.rawPermissions=this.rawPermissions.filter(p=>{return!p.includes(permissionString);});}});});},clearPermission(index){let currentRole=this.permissions[index].role;this.rawPermissions=this.rawPermissions.filter(p=>{let{type,role}=this.parsePermission(p);return role!==currentRole;});},removePermission(index){let row=this.permissions.splice(index,1);if(row.length===1){this.rawPermissions=this.rawPermissions.filter(p=>!p.includes(row[0].role));}},parsePermission(permission){let parts=permission.split('(');let type=parts[0];let role=parts[1].replace(')','').replace(' ','').replaceAll('"','');return{type,role};},buildPermission(type,role){return`${type}("${role}")`},parseInputPermission(key){if(key==='delete'){return'xdelete';} return key;},parseOutputPermission(key){if(key==='xdelete'){return'delete';} return key;},validate(formId,index){const form=document.getElementById(formId);const input=document.getElementById(`${formId}Input${index}`);const permission=this.permissions[index];input.setCustomValidity('');if(permission.role===''){input.setCustomValidity('Role is required');}else if(!Object.entries(permission).some(([k,v])=>!k.includes('role')&&v)){input.setCustomValidity('No permissions selected');}else if(this.permissions.some(p=>p.role===permission.role&&p!==permission)){input.setCustomValidity('Role entry already exists');} return form.reportValidity();},prevent(event){event.preventDefault();event.stopPropagation();}}));});})(window);(function(window){"use strict";window.ls.view.add({selector:"data-service",controller:function(element,view,container,form,alerts,expression,window){let action=element.dataset["service"];let service=element.dataset["name"]||null;let event=expression.parse(element.dataset["event"]);let confirm=element.dataset["confirm"]||"";let loading=element.dataset["loading"]||"";let loaderId=null;let scope=element.dataset["scope"]||"sdk";let success=element.dataset["success"]||"";let failure=element.dataset["failure"]||"";let running=false;let callbacks={hide:function(){return function(){return element.style.opacity='0';};},reset:function(){return function(){if("FORM"===element.tagName){return element.reset();} diff --git a/public/dist/scripts/app.js b/public/dist/scripts/app.js index 40edce16e7..bbdda3c914 100644 --- a/public/dist/scripts/app.js +++ b/public/dist/scripts/app.js @@ -607,7 +607,7 @@ this.rawPermissions=permissions;permissions.map(p=>{let{type,role}=this.parsePer if(existing===undefined){let newPermission={role,create:false,read:false,update:false,xdelete:false,};newPermission[type]=true;this.permissions.push(newPermission);} if(index!==-1){existing[type]=true;this.permissions[index]=existing;}});},addPermission(formId){if(this.permissions.length>0&&!this.validate(formId,this.permissions.length-1)){return;} this.permissions.push({role:'',create:false,read:false,update:false,xdelete:false,});},updatePermission(index){setTimeout(()=>{const permission=this.permissions[index];Object.keys(permission).forEach(key=>{if(key==='role'){return;} -const parsedKey=this.parseOutputPermission(key);const permissionString=this.buildPermission(parsedKey,permission.role);if(permission[key]){if(!this.rawPermissions.includes(permissionString)){this.rawPermissions.push(permissionString);}}else{this.rawPermissions=this.rawPermissions.filter(p=>{return!p.includes(permissionString);});}});});},removePermission(index){let row=this.permissions.splice(index,1);if(row.length===1){this.rawPermissions=this.rawPermissions.filter(p=>!p.includes(row[0].role));}},parsePermission(permission){let parts=permission.split('(');let type=parts[0];let role=parts[1].replace(')','').replace(' ','').replaceAll('"','');return{type,role};},buildPermission(type,role){return`${type}("${role}")`},parseInputPermission(key){if(key==='delete'){return'xdelete';} +const parsedKey=this.parseOutputPermission(key);const permissionString=this.buildPermission(parsedKey,permission.role);if(permission[key]){if(!this.rawPermissions.includes(permissionString)){this.rawPermissions.push(permissionString);}}else{this.rawPermissions=this.rawPermissions.filter(p=>{return!p.includes(permissionString);});}});});},clearPermission(index){let currentRole=this.permissions[index].role;this.rawPermissions=this.rawPermissions.filter(p=>{let{type,role}=this.parsePermission(p);return role!==currentRole;});},removePermission(index){let row=this.permissions.splice(index,1);if(row.length===1){this.rawPermissions=this.rawPermissions.filter(p=>!p.includes(row[0].role));}},parsePermission(permission){let parts=permission.split('(');let type=parts[0];let role=parts[1].replace(')','').replace(' ','').replaceAll('"','');return{type,role};},buildPermission(type,role){return`${type}("${role}")`},parseInputPermission(key){if(key==='delete'){return'xdelete';} return key;},parseOutputPermission(key){if(key==='xdelete'){return'delete';} return key;},validate(formId,index){const form=document.getElementById(formId);const input=document.getElementById(`${formId}Input${index}`);const permission=this.permissions[index];input.setCustomValidity('');if(permission.role===''){input.setCustomValidity('Role is required');}else if(!Object.entries(permission).some(([k,v])=>!k.includes('role')&&v)){input.setCustomValidity('No permissions selected');}else if(this.permissions.some(p=>p.role===permission.role&&p!==permission)){input.setCustomValidity('Role entry already exists');} return form.reportValidity();},prevent(event){event.preventDefault();event.stopPropagation();}}));});})(window);(function(window){"use strict";window.ls.view.add({selector:"data-service",controller:function(element,view,container,form,alerts,expression,window){let action=element.dataset["service"];let service=element.dataset["name"]||null;let event=expression.parse(element.dataset["event"]);let confirm=element.dataset["confirm"]||"";let loading=element.dataset["loading"]||"";let loaderId=null;let scope=element.dataset["scope"]||"sdk";let success=element.dataset["success"]||"";let failure=element.dataset["failure"]||"";let running=false;let callbacks={hide:function(){return function(){return element.style.opacity='0';};},reset:function(){return function(){if("FORM"===element.tagName){return element.reset();} diff --git a/public/scripts/permissions-matrix.js b/public/scripts/permissions-matrix.js index 81a869a8f4..5196e1cbc1 100644 --- a/public/scripts/permissions-matrix.js +++ b/public/scripts/permissions-matrix.js @@ -75,6 +75,14 @@ }); }); }, + clearPermission(index) { + let currentRole = this.permissions[index].role; + this.rawPermissions = this.rawPermissions.filter(p => { + let {type, role} = this.parsePermission(p); + + return role !== currentRole; + }); + }, removePermission(index) { let row = this.permissions.splice(index, 1); if (row.length === 1) { From 85ce646e0c9eed1fa7288848328ee746a4667155 Mon Sep 17 00:00:00 2001 From: Jake Barnby Date: Tue, 20 Sep 2022 22:04:15 +1200 Subject: [PATCH 9/9] Add back prevent enter --- app/views/console/comps/permissions-matrix.phtml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/views/console/comps/permissions-matrix.phtml b/app/views/console/comps/permissions-matrix.phtml index 80a424fc46..e912f26629 100644 --- a/app/views/console/comps/permissions-matrix.phtml +++ b/app/views/console/comps/permissions-matrix.phtml @@ -81,6 +81,7 @@ $escapedPermissions = \array_map(function ($perm) { list="types" type="text" x-model="permission.role" + @keydown.enter="prevent($event)" @keydown="clearPermission(index)" @keyup="updatePermission(index)"/>