{"id":37007602,"url":"https://github.com/conedevelopment/policy","last_synced_at":"2026-01-14T00:49:08.044Z","repository":{"id":56957270,"uuid":"190190376","full_name":"conedevelopment/policy","owner":"conedevelopment","description":"Using Laravel's authorization on the front-end.","archived":true,"fork":false,"pushed_at":"2021-03-02T07:21:08.000Z","size":53,"stargazers_count":97,"open_issues_count":0,"forks_count":6,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-11-22T05:20:24.706Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://pineco.de/implementing-laravels-authorization-front-end/","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/conedevelopment.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-06-04T11:45:11.000Z","updated_at":"2023-01-28T00:56:43.000Z","dependencies_parsed_at":"2022-08-21T04:40:23.123Z","dependency_job_id":null,"html_url":"https://github.com/conedevelopment/policy","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/conedevelopment/policy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/conedevelopment%2Fpolicy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/conedevelopment%2Fpolicy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/conedevelopment%2Fpolicy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/conedevelopment%2Fpolicy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/conedevelopment","download_url":"https://codeload.github.com/conedevelopment/policy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/conedevelopment%2Fpolicy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28406652,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T00:40:43.272Z","status":"ssl_error","status_checked_at":"2026-01-14T00:40:42.636Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-14T00:49:06.991Z","updated_at":"2026-01-14T00:49:08.026Z","avatar_url":"https://github.com/conedevelopment.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Policy\n\nUsing Laravel's authorization on the front-end.\n\nA nice tool for SPAs and front-end heavy applications.\n\nIf you want to see behind the package, we suggest to read this post:\n[Implementing Laravel’s Authorization on the Front-End](https://pineco.de/implementing-laravels-authorization-front-end/).\n\n### Table of contents\n\n1. [Getting Started](#getting-started)\n2. [Publishing and setting up the JavaScript library](#publishing-and-setting-up-the-javascript-library)\n   - [Setting up the Gate.js](#setting-up-the-gatejs)\n   - [Initializing a gate instance](#initializing-a-gate-instance)\n   - [Passing the user to the gate instance](#passing-the-user-to-the-gate-instance)\n   - [Using it as a Vue service](#using-it-as-a-vue-service)\n   - [The @currentUser blade directive](#the-currentuser-blade-directive)\n3. [Using the policies and the Gate.js](#using-the-policies-and-the-gatejs)\n   - [The available methods](#the-available-methods)\n   - [Adding the UsesModelName trait to the models](#adding-the-usesmodelname-trait-to-the-models)\n   - [Generating policies with artisan](#generating-policies-with-artisan)\n   - [Writing the policy rules](#writing-the-policy-rules)\n4. [Example](#example)\n5. [Contribute](#contribute)\n\n## Getting started\n\nYou can install the package with composer, running the `composer require thepinecode/policy` command.\n\nSince the package supports auto-discovery, Laravel will register the service provider automatically behind the scenes.\n\nIn some cases you may disable auto-discovery for this package.\nYou can add the provider class to the `dont-discover` array to disable it.\nThen you need to register it manually again.\n\n## Publishing and setting up the JavaScript library\n\nBy default the package provides a `Gate.js` file, that will handle the policies.\nUse the `php artisan vendor:publish` command and choose the `Pine\\Policy\\PolicyServiceProvider` provider.\nAfter publishing you can find your fresh copy in the `resources/js/policies` folder if you are using Laravel 5.7+.\nIf your application is lower than 5.7, the JS will be published in the `resources/assets/js/policies`.\n\n### Setting up the Gate.js\n\nThen you can import the `Gate` class and assign it to the `window` object.\n\n```js\nimport Gate from './policies/Gate';\nwindow.Gate = Gate;\n```\n\n### Initializing a gate instance\n\nFrom this point you can initialize the translation service anywhere from your application.\n\n```js\nlet gate = new Gate;\n```\n\n### Passing the user to the gate instance\n\nThe `Gate` object requires a passed user to work properly. This can be a `string` or an `object`.\nBy default, it looks for the `window['user']` object, however you may customize the key or the object itself.\n\n```js\nlet gate = new Gate; // window['user']\n\nlet gate = new Gate('admin'); // window['admin']\n\nlet gate = new Gate({ ... }); // uses the custom object\n```\n\n\u003e Note, you can pass any object as a *user*.\n\u003e If you pass a team or a group object, it works as well. Since you define the logic behind the `Gate`,\n\u003e you can pass anything you wish.\n\n### Using it as a Vue service\n\nIf you want to use it from Vue templates directly you can extend Vue with this easily.\n\n```js\nVue.prototype.$Gate = new Gate;\n```\n```html\n\u003ctemplate\u003e\n    \u003cdiv v-if=\"$Gate.allow('view', model)\"\u003e...\u003c/div\u003e\n\u003c/template\u003e\n```\n\n```js\ncomputed: {\n    hasPermission: {\n        return this.$Gate.allow('view', this.model);\n    }\n}\n```\n\n### The @currentUser blade directive\n\nTo make it quicker, the package comes with a `@currentUser` blade directive.\nThis does nothing more, but to print the currently authenticated user as `JSON` and assign it to the `window` object.\n\n```html\n@currentUser\n\n\u003c!-- Result --\u003e\n\u003cscript\u003ewindow['user'] = { ... };\u003c/script\u003e\n```\n\nYou may override the default key for the user. You can do that by passing a string to the blade directive.\n\n```html\n@currentUser ('admin')\n\n\u003c!-- Result --\u003e\n\u003cscript\u003ewindow['admin'] = { ... };\u003c/script\u003e\n```\n\n\u003e If there is no authenticated user, the value will be `null`.\n\n## Using the policies and the Gate.js\n\n### The available methods\n\n#### allow()\n\nThe `allow()` accepts two parameters. The first is the action to perform, the second is the **model object** or the **model name**, like in Laravel.\n\n\u003e Note: **model name** should be a lower case version of the actual model name in Laravel: for example `Comment` becomes `comment`.\n\n```js\ngate.allow('view', model);\n\ngate.allow('create', 'comment');\n```\n\n#### deny()\n\nThe `deny()` has the same signature like `allow()` but it will negate its return value.\n\n```js\ngate.deny('view', model);\n\ngate.deny('create', 'comment');\n```\n\n#### before()\n\nLike in Laravel, in the `before()` method you can provide a custom logic to check for special conditions.\nIf the condition passes, the rest of the policy rules in the `allow()` or `deny()` won't run at all.\nHowever if the condition fails, the policy rules will get place.\nTo use the `before()` method, you may extend the gate object and define your custom logic.\n\n```js\nGate.prototype.before = function () {\n    return this.user.is_admin;\n}\n```\n\n\u003e Please note, to use the `this` object correctly,\n\u003e **use the traditional function signature instead of the arrow (() =\u003e {}) functions**.\n\n### Adding the `UsesModelName` trait to the models\n\nSince, the policies use real JSON shaped eloquent models, the models have to use the  `Pine\\Policy\\UsesModelName`\ntrait that generates the proper model name. This model name attribute is used for pairing the proper policy with \nthe model by the `Gate.js`.\n\n```php\nuse Pine\\Policy\\UsesModelName;\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass Comment extends Model\n{\n    use UsesModelName;\n\n    protected $appends = ['model_name'];\n}\n```\n\n\u003e Please note, to be able to use this attribute on the front-end, the attribute has to be appended to the JSON form.\n\u003e You can read more about appending values to JSON in the\n\u003e [docs](https://laravel.com/docs/master/eloquent-serialization#appending-values-to-json).\n\n### Generating policies with artisan\n\nThe package comes with an artisan command by default, that helps you to generate your JavaScript policies easily.\nTo make a policy, run the `php artisan make:js-policy Model` command, where the `Model` is the model's name.\n\n```sh\nphp artisan make:js-policy Comment\n```\n\nThis command will create the `CommentPolicy.js` file next to the `Gate.js` in the `resources/js/policies` directory.\nIf you are using lower than Laravel 5.7, the policies will be generated in the `resources/assets/js/policies` directory.\n\n\u003e Note, the command will append the `Policy` automatically in the file name.\n\u003e It means you may pass only the model name when running the command.\n\nAfter you generated the policy files, use `npm` to compile all the JavaScript, including policies.\n\n***\n\n#### Important!\n\n**The policies are registered automatically**. It means, no need for importing them manually.\nThe gate instance will **automatically** populate the policies.\nEvery policy will be used where it matches with the model's `model_name` attribute.\n\nBased on\n[Laravel's default app.js](https://github.com/laravel/laravel/blob/master/resources/js/app.js#L19-L20)\nthe Gate instance\n[registers the policies automatically](https://github.com/thepinecode/policy/blob/master/resources/js/Gate.js#L14-L18)\nwhen calling `npm run dev`, `npm run prod` and so on.\n\n***\n\n### Writing the policy rules\n\nPolicies – like in Laravel – have the following methods by default:\n`viewAny`, `view`, `create`, `update`, `restore`, `delete` and `forceDelete`.\nOf course, you can use custom methods as well, policies are fully customizables.\n\n```js\n...\n\nview(user, model)\n{\n    return user.id == model.user_id;\n}\n\ncreate(user)\n{\n    return user.is_admin;\n}\n\napprove(user, model)\n{\n    return user.is_editor \u0026\u0026 user.id == model.user_id;\n}\n\n...\n```\n\n## Example\n\n```js\n// app.js\nVue.prototype.$Gate = new Gate;\n\nVue.component('posts', {\n    mounted() {\n        axios.get('/api/posts')\n            .then(response =\u003e this.posts = response.data);\n    },\n    data() {\n        return {\n            posts: [],\n        };\n    },\n    template: `\n        \u003cul\u003e\u003cli v-for=\"post in posts\" v-if=\"$Gate.allow('update', post)\"\u003e\u003c/li\u003e\u003c/ul\u003e\n        \u003cbutton v-if=\"$Gate.allow('create', 'post')\"\u003eCreate post\u003c/button\u003e\n    `\n});\n\nlet app = new Vue({\n    //\n})\n```\n\n```html\n\u003cbody\u003e\n    \u003cposts\u003e\u003c/posts\u003e\n\n    @currentUser\n    \u003cscript src=\"{{ asset('js/app.js') }}\"\u003e\u003c/script\u003e\n\u003c/body\u003e\n```\n\n\n## Contribute\n\nIf you found a bug or you have an idea connecting the package, feel free to open an issue.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconedevelopment%2Fpolicy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fconedevelopment%2Fpolicy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fconedevelopment%2Fpolicy/lists"}