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
19 changes: 16 additions & 3 deletions src/hooks.server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { Handle } from '@sveltejs/kit';
import { authService, canAccessAdminArea, ensureAuthReady } from './modules/auth';
import { authService, cancanService, ensureAuthReady } from './modules/auth';
import { ensureOrganizationReady, organizationService } from './modules/organization';
import { getGitDb } from '$lib/server/gitdb';

getGitDb();
Expand All @@ -10,6 +11,8 @@ export const handle: Handle = async ({ event, resolve }) => {
}

await ensureAuthReady();
await ensureOrganizationReady();


const sessionCookie = event.cookies.get('pos_session');
const currentUser = await authService.resolveAuthenticatedUser(sessionCookie);
Expand All @@ -22,8 +25,18 @@ export const handle: Handle = async ({ event, resolve }) => {
return new Response(null, { status: 302, headers: { location: '/login' } });
}

if (event.url.pathname.startsWith('/settings') || event.url.pathname.startsWith('/api/system')) {
if (!canAccessAdminArea(currentUser)) {
const organizationSettingsMatch = event.url.pathname.match(/^\/org\/([^/]+)\/settings/);
if (organizationSettingsMatch) {
const organization = await organizationService.tryFindBySlug(organizationSettingsMatch[1]);
if (!organization || !(await cancanService.canManageOrganization(currentUser, organization.id))) {
return new Response(null, { status: 302, headers: { location: '/' } });
}
} else if (
event.url.pathname.startsWith('/cluster-settings') ||
event.url.pathname.startsWith('/api/system') ||
event.url.pathname.startsWith('/api/organizations')
) {
if (!cancanService.canAccessAdminArea(currentUser)) {
return new Response(null, { status: 302, headers: { location: '/' } });
}
}
Expand Down
36 changes: 26 additions & 10 deletions src/lib/components/AppNavbar.svelte
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<script lang="ts">
import { onMount } from 'svelte';
import { ChevronDown, FolderKanban, LogOut, UserRound } from 'lucide-svelte';
import { Building2, ChevronDown, FolderKanban, LogOut, UserRound } from 'lucide-svelte';

type NavbarUser = { username: string; role: { name: string } | string | null };

export let user: NavbarUser | null = null;
export let projects: { id: string; name: string; slug: string }[] = [];
export let organizationSlug = 'gitops';
export let organizationSlug: string | null = 'gitops';
export let projectSlug = '';

let showUserDropdown = false;
Expand Down Expand Up @@ -89,7 +89,13 @@
<div
class="absolute left-0 z-50 mt-2 w-64 overflow-hidden rounded-2xl border border-slate-200 bg-white shadow-xl"
>
{#if projects.length === 0}
{#if !organizationSlug}
<p class="px-4 py-3 text-sm text-slate-500">
No organization selected. <a href="/cluster-settings/orgs" class="underline"
>Choose one</a
>.
</p>
{:else if projects.length === 0}
<p class="px-4 py-3 text-sm text-slate-500">No hay proyectos activos.</p>
{:else}
<div class="max-h-72 overflow-y-auto py-1">
Expand All @@ -109,13 +115,15 @@
</div>
{/if}

<a
href={`/org/${organizationSlug}/overview`}
on:click={closeProjectDropdown}
class="block border-t border-slate-100 bg-slate-50 px-4 py-2.5 text-sm font-medium text-slate-700 hover:bg-slate-100"
>
View all projects
</a>
{#if organizationSlug}
<a
href={`/org/${organizationSlug}/overview`}
on:click={closeProjectDropdown}
class="block border-t border-slate-100 bg-slate-50 px-4 py-2.5 text-sm font-medium text-slate-700 hover:bg-slate-100"
>
View all projects
</a>
{/if}
</div>
{/if}
</div>
Expand Down Expand Up @@ -159,6 +167,14 @@
<UserRound class="h-4 w-4" />
Profile
</a>
<a
href="/org"
on:click={closeUserDropdown}
class="flex items-center gap-2 px-4 py-3 text-sm font-medium text-slate-700 transition-colors hover:bg-slate-50"
>
<Building2 class="h-4 w-4" />
Change Organization
</a>
<form action="/api/auth/logout" method="POST" on:submit={closeUserDropdown}>
<button
type="submit"
Expand Down
106 changes: 84 additions & 22 deletions src/lib/components/AppSidebar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { page } from '$app/stores';
import {
BarChart3,
Building2,
ChevronDown,
ChevronRight,
Database,
Expand All @@ -20,7 +21,7 @@
Users,
Layers,
HardDrive,
Bot
Bot,
} from 'lucide-svelte';

type NavItem = { label: string; href: string; icon: ComponentType };
Expand All @@ -29,8 +30,9 @@

export let pathname = '/';
export let isConfigured = false;
export let collapsed = false;
export let organizationSlug = 'gitops';
export let collapsed = true;
export let organizationSlug: string | null = null;
export let organizationName: string | null = null;
export let projects: {
slug: string;
modules?: { vault: boolean; openreport: boolean; stateiac: boolean };
Expand All @@ -54,13 +56,21 @@
{
name: 'Overview',
icon: LayoutDashboard,
items: [
{
label: 'Overview',
href: `/org/${organizationSlug}/overview`,
icon: LayoutDashboard,
},
],
items: organizationSlug
? [
{
label: 'Overview',
href: `/org/${organizationSlug}/overview`,
icon: LayoutDashboard,
},
]
: [
{
label: 'Seleccionar organización',
href: '/cluster-settings/orgs',
icon: Building2,
},
],
},
],
},
Expand Down Expand Up @@ -108,7 +118,11 @@
items: [
{ label: 'Stacks', href: `${projectBase}/state-iac/stacks`, icon: Layers },
{ label: 'Backends', href: `${projectBase}/state-iac/backends`, icon: HardDrive },
{ label: 'Deployments', href: `${projectBase}/state-iac/deployments`, icon: GitBranch }
{
label: 'Deployments',
href: `${projectBase}/state-iac/deployments`,
icon: GitBranch,
},
],
},
],
Expand Down Expand Up @@ -136,7 +150,11 @@
icon: Shield,
},
{ label: 'Audit', href: `${projectBase}/settings/audit`, icon: ScrollText },
{ label: 'Server Keys', href: `${projectBase}/settings/server-keys`, icon: Shield },
{
label: 'Server Keys',
href: `${projectBase}/settings/server-keys`,
icon: Shield,
},
],
},
],
Expand All @@ -146,15 +164,57 @@
{
name: 'Sistema',
modules: [
...(organizationSlug
? [
{
name: 'Organization Settings',
icon: Settings,
items: [
{
label: 'Projects',
href: `/org/${organizationSlug}/settings/projects`,
icon: FolderKanban,
},
{
label: 'Global',
href: `/org/${organizationSlug}/settings/global`,
icon: Shield,
},
{
label: 'Users',
href: `/org/${organizationSlug}/settings/users`,
icon: Users,
},
{
label: 'Roles & Permissions',
href: `/org/${organizationSlug}/settings/roles-permissions`,
icon: Users,
},
{
label: 'System & Backup',
href: `/org/${organizationSlug}/settings/system-backup`,
icon: Database,
},
{
label: 'Server Access Keys',
href: `/org/${organizationSlug}/settings/server-access-keys`,
icon: KeyRound,
},
],
},
]
: []),
{
name: 'Settings',
icon: Settings,
name: 'Cluster Settings',
icon: Building2,
items: [
{ label: 'Projects', href: '/settings/projects', icon: FolderKanban },
{ label: 'Autentication', href: '/settings/authentication', icon: Shield },
{ label: 'Roles & Permissions', href: '/settings/roles-permissions', icon: Users },
{ label: 'System & Backup', href: '/settings/system-backup', icon: Database },
{ label: 'Server Access Keys', href: '/settings/server-access-keys', icon: KeyRound },
{ label: 'Organizations', href: '/cluster-settings/orgs', icon: Building2 },
{
label: 'Roles & Permissions',
href: '/cluster-settings/roles-permissions',
icon: Shield,
},
{ label: 'Users', href: '/cluster-settings/users', icon: Users },
],
},
],
Expand All @@ -181,12 +241,12 @@
<aside class="flex h-full flex-col gap-4">
<div class="border-b border-slate-200 px-1 pb-4">
<div class="flex items-center justify-between gap-3">
{#if !collapsed}
{#if !collapsed && organizationName}
<div class="min-w-0">
<p class="text-[10px] font-semibold uppercase tracking-[0.22em] text-slate-500">
Organization
</p>
<h2 class="mt-1 text-sm font-semibold text-slate-900">GitOps</h2>
<h2 class="mt-1 truncate text-sm font-semibold text-slate-900">{organizationName}</h2>
</div>
{/if}

Expand All @@ -208,7 +268,9 @@

{#if !isConfigured}
<a
href="/settings/storage"
href={organizationSlug
? `/org/${organizationSlug}/settings/storage`
: '/cluster-settings/orgs'}
class="flex items-center gap-3 rounded-md border border-amber-200 bg-amber-50 p-3 text-amber-950 transition-colors hover:border-amber-300 hover:bg-amber-100 {collapsed
? 'justify-center'
: 'items-start'}"
Expand Down
Loading
Loading