Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"env": {
"browser": true,
"es6": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:vue/vue3-recommended"
],
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly",
"_": true,
"axios": true
},
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module"
},
"plugins": [
"vue"
],
"rules": {
}
}
2 changes: 2 additions & 0 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ jobs:
redis-version: 6 # optional, default is latest, was 5
- name: Install Dependencies
run: composer install --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: Run test & coverage
run: vendor/bin/pest --coverage --min=85
# - name: Test & publish code coverage
# uses: paambaati/codeclimate-action@v2.6.0
# env:
Expand Down
63 changes: 29 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,59 +5,54 @@
[![GitHub Code Style Action Status](https://img.shields.io/github/workflow/status/seatplus/api/Check%20&%20fix%20styling?label=code%20style)](https://github.com/seatplus/api/actions?query=workflow%3A"Check+%26+fix+styling"+branch%3Amain)
[![Total Downloads](https://img.shields.io/packagist/dt/seatplus/api.svg?style=flat-square)](https://packagist.org/packages/seatplus/api)

---
This repo can be used as to scaffold a Laravel package. Follow these steps to get started:

1. Press the "Use template" button at the top of this repo to create a new repo with the contents of this api
2. Run "./configure-api.sh" to run a script that will replace all placeholders throughout all the files
3. Remove this block of text.
4. Have fun creating your package.
5. If you need help creating a package, consider picking up our <a href="https://laravelpackage.training">Laravel Package Training</a> video course.
---

This is where your description should go. Limit it to a paragraph or two. Consider adding a small example.
## Installation

## Support us

[<img src="https://github-ads.s3.eu-central-1.amazonaws.com/api.jpg?t=1" width="419px" />](https://spatie.be/github-ad-click/api)

We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us).
## Usage

We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards).
There are several ways of passing the API token to your application. We'll discuss each of these approaches while using the Guzzle HTTP library to demonstrate their usage. You may choose any of these approaches based on the needs of your application.

## Installation
### Query Strings

You can install the package via composer:
Your application's API consumers may specify their token as an `api_token` query string value:

```bash
composer require seatplus/api
```php
$response = $client->request('GET', '/api/user?api_token='.$token);
```

You can publish and run the migrations with:
### Request Payload

```bash
php artisan vendor:publish --provider="Seatplus\Api\ApiServiceProvider" --tag="api-migrations"
php artisan migrate
```
Your application's API consumers may include their API token in the request's form parameters as an `api_token`:

You can publish the config file with:
```bash
php artisan vendor:publish --provider="Seatplus\Api\ApiServiceProvider" --tag="api-config"
```php
$response = $client->request('POST', '/api/user', [
'headers' => [
'Accept' => 'application/json',
],
'form_params' => [
'api_token' => $token,
],
]);
```

This is the contents of the published config file:
### Bearer Token

Your application's API consumers may provide their API token as a `Bearer` token in the `Authorization` header of the request:

```php
return [
];
$response = $client->request('POST', '/api/user', [
'headers' => [
'Authorization' => 'Bearer '.$token,
'Accept' => 'application/json',
],
]);
```

## Usage
## Documentation

```php
$api = new Seatplus\Api();
echo $api->echoPhrase('Hello, Spatie!');
```
[![Run in Postman](https://run.pstmn.io/button.svg)](https://app.getpostman.com/run-collection/13012975-234f6f65-12e0-4d5b-ae35-a6e0d17ffc91?action=collection%2Ffork&collection-url=entityId%3D13012975-234f6f65-12e0-4d5b-ae35-a6e0d17ffc91%26entityType%3Dcollection%26workspaceId%3D99c4cf22-1a90-4315-91cf-3899990b05c7)

## Testing

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"require": {
"php": "^8.0",
"laravel/sanctum": "^2.11",
"seatplus/web": "*"
"seatplus/web": "0.8.17"
},
"require-dev": {
"nunomaduro/collision": "^5.3",
Expand Down
5 changes: 5 additions & 0 deletions config/api.permissions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?php

return [
'API: can list and access users'
];
12 changes: 12 additions & 0 deletions config/api.sidebar.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

return [
'api' => [
[
'name' => 'Api',
'permission' => 'can use api',
'route' => 'api.index',
'icon' => 'CubeTransparentIcon'
],
]
];
38 changes: 38 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"private": true,
"scripts": {
"dev": "npm run development",
"development": "mix",
"watch": "mix watch",
"watch-poll": "mix watch -- --watch-options-poll=1000",
"hot": "mix watch --hot",
"prod": "npm run production",
"production": "mix --production"
},
"devDependencies": {
"@vue/compiler-sfc": "^3.0.7",
"acorn": "^8.0",
"autoprefixer": "^10.2.5",
"axios": "^0.21.1",
"eslint": "^7.22.0",
"eslint-plugin-vue": "^7.7.0",
"resolve-url-loader": "^3.1.2",
"vue": "^3.0.0-0",
"vue-loader": "^16.1.2",
"vue-template-compiler": "^2.6.12"
},
"dependencies": {
"@headlessui/vue": "^1.0.0",
"@heroicons/vue": "^1.0.0",
"@inertiajs/inertia": "^0.8.4",
"@inertiajs/inertia-vue3": "^0.3.5",
"@inertiajs/progress": "^0.2.4",
"@tailwindcss/aspect-ratio": "^0.2.0",
"@tailwindcss/forms": "^0.3.2",
"@tailwindcss/typography": "^0.4.0",
"dayjs": "^1.10.4",
"lodash": "^4.17.20",
"uuid": "^8.3.2",
"vue3-chart-v2": "^0.8.1"
}
}
5 changes: 4 additions & 1 deletion phpunit.xml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
>
<testsuites>
<testsuite name="Seatplus Test Suite">
<directory>tests</directory>
<directory suffix=".php">tests/Integration</directory>
</testsuite>
</testsuites>
<coverage>
Expand All @@ -33,6 +33,9 @@
<clover outputFile="build/logs/clover.xml"/>
</report>
</coverage>
<php>
<env name="APP_KEY" value="AckfSECXIvnK5r28GVIWUAxmbBSjTsmF" />
</php>
<logging>
<junit outputFile="build/report.junit.xml"/>
</logging>
Expand Down
177 changes: 177 additions & 0 deletions resources/js/Pages/Api/Index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
<template>
<div class="space-y-3">
<teleport to="#head">
<title>{{ title(pageTitle) }}</title>
</teleport>

<PageHeader>
{{ pageTitle }}
</PageHeader>

<div class="bg-white shadow overflow-hidden sm:rounded-md">
<ul class="divide-y divide-gray-200">
<li
v-for="(token, tokenIdx) in tokens"
:key="tokenIdx"
class="px-4 py-4 sm:px-6"
>
<!-- Your content -->
<div class="flex justify-between">
<div class="flex flex-col">
<span class="text-gray-900 block text-sm font-medium">
{{ token.name }}
</span>
<span class="text-gray-500 block text-sm">
***************
</span>
</div>
<div>
<div class="mt-5 sm:mt-0 sm:ml-6 sm:flex-shrink-0 sm:flex sm:items-center">
<button
type="button"
class="inline-flex items-center px-4 py-2 border border-transparent shadow-sm font-medium rounded-md text-red-700 bg-red-100 hover:bg-red-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:text-sm"
@click="remove(token.id)"
>
Delete
</button>
</div>
</div>
</div>
</li>
<li class="px-4 py-4 sm:px-6 space-y-3">
<!-- Your content -->
<div class="flex justify-between">
<div
v-if="plainTextToken"
class="flex flex-col"
>
<span class="text-gray-900 block text-sm font-medium">
{{ form.token_name }}
</span>
<span class="text-gray-500 block text-sm">
{{ plainTextToken }}
</span>
</div>
<div
v-else
class="w-2/4"
>
<label
for="token"
class="block text-sm font-medium text-gray-700"
>
Token Name
</label>
<div class="mt-1">
<input
id="token"
v-model="form.token_name"
name="token"
type="text"
required="required"
class="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
>
</div>
</div>
<div v-if="!plainTextToken">
<div class="mt-5 sm:mt-0 sm:ml-6 sm:flex-shrink-0 sm:flex sm:items-center">
<button
type="submit"
class="inline-flex items-center px-4 py-2 border border-transparent shadow-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:text-sm"
@click="submit"
>
Create token
</button>
</div>
</div>
</div>
<div v-if="!plainTextToken">
<h3 class="text-lg leading-6 font-medium text-gray-900">
Permissions
</h3>
<p class="mt-1 text-sm text-gray-500">
Select all permissions which should be carried by the token.
</p>
</div>
<div class="grid sm:grid-cols-2 gap-4">
<PermissionToggle
v-for="permission in permissions"
:key="permission"
v-model:abilities="form.abilities"
:permission="permission"
/>
</div>
</li>
</ul>
</div>
</div>
</template>

<script>
import PageHeader from "@/Shared/Layout/PageHeader";
import {ref} from "vue";
import route from 'ziggy';
import { Inertia } from '@inertiajs/inertia'
import PermissionToggle from "./PermissionToggle";
import { useForm } from '@inertiajs/inertia-vue3'

export default {
name: "Index",
components: {
PermissionToggle, PageHeader
},
props: {
'tokens': {
type: Array,
required: true
},
'permissions': {
type: Array,
required: true
},
'plainTextToken': {
type: String,
required: false,
default: ''
}
},
data() {
const token_name = ref('')
const abilities = ref([])

const form = useForm({
token_name: '',
abilities: [],
})

const submit = () => {
form.value.post(route('create.api.token'))

/* axios.post(route('create.api.token'), {
token_name: token_name.value,
abilities: abilities.value
})
.then(res => plainTextToken.value = res.data.token)
.catch(error => console.log(error))*/
}

const remove = (tokenId) => axios
.delete(route('delete.api.token', tokenId))
.then(() => Inertia.reload())

return {
pageTitle: 'Api Keys',
items: [],
abilities,
token_name,
submit,
remove,
form
}
}
}
</script>

<style scoped>

</style>
Loading