mirror of
https://github.com/wireadmin/wireadmin
synced 2025-06-26 18:28:06 +00:00
update
This commit is contained in:
parent
b56961377b
commit
93f9b506fa
@ -2,6 +2,7 @@
|
|||||||
"useTabs": false,
|
"useTabs": false,
|
||||||
"semi": true,
|
"semi": true,
|
||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
|
"jsxSingleQuote": true,
|
||||||
"trailingComma": "all",
|
"trailingComma": "all",
|
||||||
"printWidth": 120,
|
"printWidth": 120,
|
||||||
"jsxBracketSameLine": true,
|
"jsxBracketSameLine": true,
|
||||||
|
@ -3,27 +3,23 @@ import { verifyToken } from '$lib/auth';
|
|||||||
import { HASHED_PASSWORD } from '$env/static/private';
|
import { HASHED_PASSWORD } from '$env/static/private';
|
||||||
|
|
||||||
export const handle: Handle = async ({ event, resolve }) => {
|
export const handle: Handle = async ({ event, resolve }) => {
|
||||||
|
|
||||||
if (!!HASHED_PASSWORD && !AUTH_EXCEPTION.includes(event.url.pathname)) {
|
if (!!HASHED_PASSWORD && !AUTH_EXCEPTION.includes(event.url.pathname)) {
|
||||||
const token = event.cookies.get('authorization');
|
const token = event.cookies.get('authorization');
|
||||||
|
const token_valid = await verifyToken(token ?? '');
|
||||||
|
|
||||||
const redirect = new Response(null, { status: 302, headers: { location: '/login' } });
|
const redirect = new Response(null, { status: 302, headers: { location: '/login' } });
|
||||||
|
const is_login_page = event.url.pathname === '/login';
|
||||||
|
|
||||||
if (!token) {
|
if (!token_valid && !is_login_page) {
|
||||||
console.log('handle', event.url.pathname, 'no token');
|
|
||||||
return redirect;
|
|
||||||
}
|
|
||||||
|
|
||||||
const token_valid = await verifyToken(token);
|
|
||||||
if (!token_valid) {
|
|
||||||
console.log('handle', event.url.pathname, 'invalid token');
|
console.log('handle', event.url.pathname, 'invalid token');
|
||||||
return redirect;
|
return redirect;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (event.url.pathname === '/login') {
|
if (token_valid && is_login_page) {
|
||||||
console.log('handle', 'already logged in');
|
console.log('handle', 'already logged in');
|
||||||
return new Response(null, { status: 302, headers: { location: '/' } });
|
return new Response(null, { status: 302, headers: { location: '/' } });
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const resp = await resolve(event);
|
const resp = await resolve(event);
|
||||||
|
|
||||||
@ -32,5 +28,4 @@ export const handle: Handle = async ({ event, resolve }) => {
|
|||||||
return resp;
|
return resp;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const AUTH_EXCEPTION = ['/api/health'];
|
||||||
const AUTH_EXCEPTION = ['/api/health', '/login'];
|
|
||||||
|
@ -16,7 +16,6 @@ export async function generateToken(): Promise<string> {
|
|||||||
export async function verifyToken(token: string): Promise<boolean> {
|
export async function verifyToken(token: string): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
const decode = jwt.verify(token, AUTH_SECRET);
|
const decode = jwt.verify(token, AUTH_SECRET);
|
||||||
console.log('decode', decode);
|
|
||||||
return !!decode;
|
return !!decode;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false;
|
return false;
|
||||||
|
20
web/src/lib/components/page/BasePage.svelte
Normal file
20
web/src/lib/components/page/BasePage.svelte
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { cn } from '$lib/utils';
|
||||||
|
import PageFooter from '$lib/components/page/PageFooter.svelte';
|
||||||
|
import PageHeader from '$lib/components/page/PageHeader.svelte';
|
||||||
|
|
||||||
|
export let rootClass: string | undefined = undefined;
|
||||||
|
let className: string | undefined = undefined;
|
||||||
|
export let showLogout: boolean = false;
|
||||||
|
export { className as class };
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="w-full min-h-screen flex justify-center px-2 md:px-6 py-2">
|
||||||
|
<div class={cn("w-full mx-auto max-w-3xl space-y-3.5", rootClass)}>
|
||||||
|
<PageHeader {showLogout} />
|
||||||
|
<main class={cn("py-2", className)}>
|
||||||
|
<slot />
|
||||||
|
</main>
|
||||||
|
<PageFooter />
|
||||||
|
</div>
|
||||||
|
</div>
|
37
web/src/lib/components/page/PageHeader.svelte
Normal file
37
web/src/lib/components/page/PageHeader.svelte
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import Logo from '$lib/assets/logo.png';
|
||||||
|
|
||||||
|
export let showLogout: boolean = false;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<header class={'w-full py-3 px-2'}>
|
||||||
|
<nav class={'w-full flex items-center justify-between'}>
|
||||||
|
<div class={'flex items-center gap-x-2 text-3xl font-medium'}>
|
||||||
|
<img src={Logo} alt="WireAdmin" width="40" height="40" />
|
||||||
|
<h1>WireAdmin</h1>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class={'flex items-center gap-x-2'}>
|
||||||
|
<a href={'https://github.com/shahradelahi/wireadmin'} title={'Giv me a star on Github'}>
|
||||||
|
<img
|
||||||
|
src={'https://img.shields.io/github/stars/shahradelahi/wireadmin.svg?style=social&label=Star'}
|
||||||
|
alt={'Giv me a star on Github'}
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
{#if showLogout}
|
||||||
|
<a href={'/logout'} class={''} title="logout">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
class="h-6 w-6 text-red-500 hover:text-red-700"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7" />
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</header>
|
12
web/src/routes/+page.server.ts
Normal file
12
web/src/routes/+page.server.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import type { Actions } from '@sveltejs/kit';
|
||||||
|
import type { PageServerLoad } from './$types';
|
||||||
|
|
||||||
|
export const load: PageServerLoad = () => {
|
||||||
|
return {};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const actions: Actions = {
|
||||||
|
default: async ({ request, cookies }) => {
|
||||||
|
return { message: 'Success!' };
|
||||||
|
},
|
||||||
|
};
|
@ -1,8 +1,20 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Button } from '$lib/components/ui/button';
|
import { Button } from '$lib/components/ui/button';
|
||||||
|
import BasePage from '$lib/components/page/BasePage.svelte';
|
||||||
|
import * as Card from '$lib/components/ui/card';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<BasePage showLogout={true}>
|
||||||
|
<div class={'flex items-center justify-between py-3 px-2'}>
|
||||||
|
<h2 class={'font-bold text-xl'}>Hello there 👋</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Card.Root>
|
||||||
|
<Card.Content>
|
||||||
<h1>Welcome to SvelteKit</h1>
|
<h1>Welcome to SvelteKit</h1>
|
||||||
<p>Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation</p>
|
<p>Visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to read the documentation</p>
|
||||||
|
|
||||||
<Button variant="outline">Button</Button>
|
<Button variant="outline">Button</Button>
|
||||||
|
</Card.Content>
|
||||||
|
</Card.Root>
|
||||||
|
</BasePage>
|
||||||
|
17
web/src/routes/login/+layout.svelte
Normal file
17
web/src/routes/login/+layout.svelte
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import PageFooter from '$lib/components/page/PageFooter.svelte';
|
||||||
|
import Logo from '$lib/assets/logo.png';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class={'w-full min-h-screen flex justify-center px-2 md:px-6 py-2'}>
|
||||||
|
<div class={'w-full mx-auto max-w-3xl flex flex-col items-center gap-y-3.5'}>
|
||||||
|
<header class={'flex items-center gap-x-2 text-3xl font-medium py-4'}>
|
||||||
|
<img src={Logo} alt="WireAdmin" width="40" height="40" />
|
||||||
|
<h1>WireAdmin</h1>
|
||||||
|
</header>
|
||||||
|
<main class={'py-4'}>
|
||||||
|
<slot />
|
||||||
|
</main>
|
||||||
|
<PageFooter />
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -1,22 +1,15 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import PageFooter from '$lib/components/page/PageFooter.svelte';
|
|
||||||
import Logo from '$lib/assets/logo.png';
|
|
||||||
import * as Form from '$lib/components/ui/form';
|
import * as Form from '$lib/components/ui/form';
|
||||||
|
import * as Card from '$lib/components/ui/card';
|
||||||
import { formSchema, type FormSchema } from './schema';
|
import { formSchema, type FormSchema } from './schema';
|
||||||
import type { SuperValidated } from 'sveltekit-superforms';
|
import type { SuperValidated } from 'sveltekit-superforms';
|
||||||
|
|
||||||
export let form: SuperValidated<FormSchema>;
|
export let form: SuperValidated<FormSchema>;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class={'w-full min-h-screen flex justify-center px-2 md:px-6 py-2'}>
|
<Card.Root>
|
||||||
<div class={'w-full mx-auto max-w-3xl flex flex-col items-center gap-y-3.5'}>
|
<Card.Content>
|
||||||
<header class={'flex items-center gap-x-2 text-3xl font-medium py-4'}>
|
<Form.Root method="POST" {form} schema={formSchema} let:config class="pt-4 space-y-8">
|
||||||
<img src={Logo} alt="WireAdmin" width="40" height="40" />
|
|
||||||
<h1>WireAdmin</h1>
|
|
||||||
</header>
|
|
||||||
<main class={'py-4'}>
|
|
||||||
<div class="w-full bg-white rounded-lg shadow-sm">
|
|
||||||
<Form.Root method="POST" {form} schema={formSchema} let:config class="p-4 space-y-8">
|
|
||||||
<div class="w-full flex items-center justify-center">
|
<div class="w-full flex items-center justify-center">
|
||||||
<div class="w-16 aspect-square flex items-center justify-center rounded-full bg-gray-200">
|
<div class="w-16 aspect-square flex items-center justify-center rounded-full bg-gray-200">
|
||||||
<i class="fas fa-user text-primary text-2xl" />
|
<i class="fas fa-user text-primary text-2xl" />
|
||||||
@ -33,8 +26,5 @@
|
|||||||
|
|
||||||
<Form.Button class="w-full">Sign In</Form.Button>
|
<Form.Button class="w-full">Sign In</Form.Button>
|
||||||
</Form.Root>
|
</Form.Root>
|
||||||
</div>
|
</Card.Content>
|
||||||
</main>
|
</Card.Root>
|
||||||
<PageFooter />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
7
web/src/routes/logout/+page.server.ts
Normal file
7
web/src/routes/logout/+page.server.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import type { PageServerLoad } from './$types';
|
||||||
|
import { redirect } from '@sveltejs/kit';
|
||||||
|
|
||||||
|
export const load: PageServerLoad = ({ cookies }) => {
|
||||||
|
cookies.delete('authorization');
|
||||||
|
throw redirect(302, '/login');
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user