Merge branch 'develop'

# Conflicts:
#	public/css/app.css
#	public/js/app.js
This commit is contained in:
Dennis
2021-09-16 09:50:07 +02:00
11 changed files with 188273 additions and 89 deletions

View File

@@ -68,6 +68,7 @@ class Kernel extends HttpKernel
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class, 'can' => \Illuminate\Auth\Middleware\Authorize::class,
'has.access' => \App\Http\Middleware\HasAccessToThisGroup::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'global.api.authenticated' => \App\Http\Middleware\GlobalApiAuthenticated::class, 'global.api.authenticated' => \App\Http\Middleware\GlobalApiAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class, 'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,

View File

@@ -10,7 +10,7 @@ class Demo
protected $safeRoutes = [ protected $safeRoutes = [
'login', 'login',
'logout', 'logout',
//'profile/toggle-theme' 'profile/toggle-theme'
]; ];
protected $allowedIps = [ protected $allowedIps = [

View File

@@ -0,0 +1,27 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
class HasAccessToThisGroup
{
public function handle(Request $request, Closure $next, $group)
{
if ($group === 'servers') {
$package = $request->user()->package ?? [];
if (
!Arr::get($package->server_permissions, 'create', false) &&
!Arr::get($package->server_permissions, 'update', false) &&
!Arr::get($package->server_permissions, 'delete', false)
) {
abort(404);
}
}
return $next($request);
}
}

View File

@@ -5,6 +5,9 @@ namespace App\Models;
use DateTimeInterface; use DateTimeInterface;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
/**
* @property mixed|string domain
*/
class Site extends Model class Site extends Model
{ {
const STATUS_BUSY = 'busy'; const STATUS_BUSY = 'busy';
@@ -95,6 +98,10 @@ class Site extends Model
public static function booted() public static function booted()
{ {
static::creating(function (self $site) {
$site->domain = strtolower($site->domain);
});
static::created(function (self $site) { static::created(function (self $site) {
$site->systemUsers()->create(); $site->systemUsers()->create();
}); });

160768
public/css/app.css vendored

File diff suppressed because one or more lines are too long

27335
public/js/app.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
<template> <template>
<Page> <Page>
<TopBar :breadcrumbs="breadcrumbs" /> <TopBar :breadcrumbs="breadcrumbs"/>
<Content> <Content>
<Container> <Container>
@@ -12,7 +12,7 @@
<PageBody> <PageBody>
<div> <div>
<ul class="grid grid-cols-1 md:grid-cols-3 gap-4"> <ul class="grid grid-cols-1 gap-4" :class="{'md:grid-cols-3': hasAccessToServers, 'md:grid-cols-2': !hasAccessToServers}">
<li class="p-6 rounded shadow bg-surface-3 transform transition duration-fast ease-in-out hover:scale-95"> <li class="p-6 rounded shadow bg-surface-3 transform transition duration-fast ease-in-out hover:scale-95">
<inertia-link :href="route('sites.index')" class="flex space-x-4"> <inertia-link :href="route('sites.index')" class="flex space-x-4">
<div> <div>
@@ -24,7 +24,7 @@
</div> </div>
</inertia-link> </inertia-link>
</li> </li>
<li class="p-6 rounded shadow bg-surface-3 transform transition duration-fast ease-in-out hover:scale-95"> <li class="p-6 rounded shadow bg-surface-3 transform transition duration-fast ease-in-out hover:scale-95" v-if="hasAccessToServers">
<inertia-link :href="route('servers.index')" class="flex space-x-4"> <inertia-link :href="route('servers.index')" class="flex space-x-4">
<div> <div>
<IconStorage class="w-6 h-6"/> <IconStorage class="w-6 h-6"/>
@@ -36,7 +36,9 @@
</inertia-link> </inertia-link>
</li> </li>
<li class="p-6 rounded shadow bg-surface-3 transform transition duration-fast ease-in-out hover:scale-95"> <li class="p-6 rounded shadow bg-surface-3 transform transition duration-fast ease-in-out hover:scale-95">
<inertia-link :href="$page.props.settings.billing ? route('profile.billing.index') : route('profile.index')" class="flex space-x-4"> <inertia-link
:href="$page.props.settings.billing ? route('profile.billing.index') : route('profile.index')"
class="flex space-x-4">
<div> <div>
<IconBox class="w-6 h-6"/> <IconBox class="w-6 h-6"/>
</div> </div>
@@ -55,7 +57,8 @@
{{ log.title }} {{ log.title }}
</template> </template>
<template #subtitle>{{ log.description }}</template> <template #subtitle>{{ log.description }}</template>
<template #suffix><span class="text-medium-emphasis">{{ log.created_at_human }}</span></template> <template #suffix><span class="text-medium-emphasis">{{ log.created_at_human }}</span>
</template>
</ListItem> </ListItem>
</List> </List>
</PageBody> </PageBody>
@@ -65,86 +68,92 @@
</template> </template>
<script> <script>
import TopBar from './components/TopBar' import TopBar from './components/TopBar'
import Container from '@/components/Container' import Container from '@/components/Container'
import Content from '@/components/Content' import Content from '@/components/Content'
import Page from '@/components/Page' import Page from '@/components/Page'
import PageHeader from '@/components/PageHeader' import PageHeader from '@/components/PageHeader'
import PageHeaderTitle from '@/components/PageHeaderTitle' import PageHeaderTitle from '@/components/PageHeaderTitle'
import PageBody from '@/components/PageBody' import PageBody from '@/components/PageBody'
import Button from '@/components/Button' import Button from '@/components/Button'
import List from '@/components/List' import List from '@/components/List'
import ListItem from '@/components/ListItem' import ListItem from '@/components/ListItem'
import StatusBubble from '@/components/StatusBubble' import StatusBubble from '@/components/StatusBubble'
import NotificationBadge from '@/components/NotificationBadge' import NotificationBadge from '@/components/NotificationBadge'
import MainLayout from '@/Layouts/MainLayout' import MainLayout from '@/Layouts/MainLayout'
import IconBox from '@/components/icons/IconBox' import IconBox from '@/components/icons/IconBox'
import IconGlobe from '@/components/icons/IconGlobe' import IconGlobe from '@/components/icons/IconGlobe'
import IconStorage from '@/components/icons/IconStorage' import IconStorage from '@/components/icons/IconStorage'
import { useNotification } from '@/hooks/notification' import {useNotification} from '@/hooks/notification'
export default { export default {
metaInfo() { metaInfo() {
return { return {
title: `${this.__('Dashboard')}`, title: `${this.__('Dashboard')}`,
} }
}, },
layout: MainLayout, layout: MainLayout,
components: { components: {
TopBar, TopBar,
Container, Container,
Content, Content,
Page, Page,
PageHeader, PageHeader,
PageHeaderTitle, PageHeaderTitle,
PageBody, PageBody,
Button, Button,
List, List,
ListItem, ListItem,
StatusBubble, StatusBubble,
NotificationBadge, NotificationBadge,
IconBox, IconBox,
IconGlobe, IconGlobe,
IconStorage, IconStorage,
}, },
props: { props: {
sites: Number, sites: Number,
servers: Number, servers: Number,
package: Object, package: Object,
logs: Array, logs: Array,
}, },
methods: { methods: {
useNotification useNotification
}, },
data () { data() {
return{ return {
breadcrumbs: [ breadcrumbs: [
{ {
title: this.$page.props.settings.name, title: this.$page.props.settings.name,
to: '/', to: '/',
}, },
{ {
title: 'Dashboard', title: 'Dashboard',
to: '/', to: '/',
}, },
], ],
} }
}, },
mounted() { computed: {
if (this.$page.props.flash.info) { hasAccessToServers () {
useNotification({ return (this.$page.props.auth.can.servers.create || this.$page.props.auth.can.servers.update || this.$page.props.auth.can.servers.delete);
variant: 'info', }
title: `Information`, },
message: this.$page.props.flash.info,
}) mounted() {
} if (this.$page.props.flash.info) {
}, useNotification({
} variant: 'info',
title: `Information`,
message: this.$page.props.flash.info,
})
}
},
}
</script> </script>

View File

@@ -29,6 +29,14 @@ export default {
breadcrumbs: Array, breadcrumbs: Array,
}, },
computed: {
hasServerAccess() {
return this.$page.props.auth.can.servers.create ||
this.$page.props.auth.can.servers.delete ||
this.$page.props.auth.can.servers.update
}
},
data() { data() {
return { return {
tabBars: [ tabBars: [
@@ -41,10 +49,10 @@ export default {
title: this.__('Sites'), title: this.__('Sites'),
to: this.route('sites.index'), to: this.route('sites.index'),
}, },
{ (this.$page.props.auth.can.servers.create || this.$page.props.auth.can.servers.update || this.$page.props.auth.can.servers.delete) ? {
title: this.__('Servers'), title: this.__('Servers'),
to: this.route('servers.index'), to: this.route('servers.index'),
}, } : null,
], ],
} }
}, },

View File

@@ -42,10 +42,10 @@ export default {
to: this.route('sites.index'), to: this.route('sites.index'),
active: this.route().current('sites.*') active: this.route().current('sites.*')
}, },
{ (this.$page.props.auth.can.servers.create || this.$page.props.auth.can.servers.update || this.$page.props.auth.can.servers.delete) ? {
title: 'Servers', title: this.__('Servers'),
to: this.route('servers.index'), to: this.route('servers.index'),
}, } : null,
], ],
} }
}, },

View File

@@ -5,8 +5,6 @@
@tailwind utilities; @tailwind utilities;
@import 'nprogress'; @import 'nprogress';
//$balloon-bg: var(--color-surface-1);
@import "~balloon-css/src/balloon"; @import "~balloon-css/src/balloon";
.bf-blur { .bf-blur {
@@ -29,3 +27,36 @@
-webkit-background-clip: text; -webkit-background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
} }
.theme--dark {
.prose {
color: var(--text-medium-emphasis);
}
.vue-simplemde {
.editor-toolbar {
border-left: 1px solid var(--color-surface-3);
border-top: 1px solid var(--color-surface-3);
border-right: 1px solid var(--color-surface-3);
.separator {
border-left: 1px solid var(--color-surface-3);
border-right: transparent;
}
a {
color: var(--text-medium-emphasis) !important;
}
a:hover {
background: var(--color-surface-3);
}
}
.CodeMirror {
background: var(--color-surface-1);
color: var(--text-medium-emphasis);
border: 1px solid var(--color-surface-3);
}
}
}

View File

@@ -75,7 +75,7 @@ Route::group(['middleware' => ['auth', 'auth.blocked']], function () {
}); });
// Server routes // Server routes
Route::group(['prefix' => 'servers', 'as' => 'servers.'], function () { Route::group(['prefix' => 'servers', 'as' => 'servers.', 'middleware' => 'has.access:servers'], function () {
Route::get('/', 'ServerController@index')->name('index'); Route::get('/', 'ServerController@index')->name('index');
Route::get('{provider}/plans-and-regions', 'ServerController@plansAndRegions')->name('plans-and-regions'); Route::get('{provider}/plans-and-regions', 'ServerController@plansAndRegions')->name('plans-and-regions');
Route::get('{server}', 'ServerController@show')->name('show'); Route::get('{server}', 'ServerController@show')->name('show');