Skip to content

Commit

Permalink
feat(katzencore): Added Authentication to Module
Browse files Browse the repository at this point in the history
  • Loading branch information
Maximilian Schleining committed Jul 15, 2024
1 parent 110c5ab commit 376a4f3
Show file tree
Hide file tree
Showing 14 changed files with 1,015 additions and 65 deletions.
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,15 @@
"devDependencies": {
"@nuxt/devtools": "^1.3.9",
"@nuxt/eslint-config": "^0.3.13",
"@nuxt/image": "^1.7.0",
"@nuxt/module-builder": "^0.8.1",
"@nuxt/schema": "^3.12.3",
"@nuxt/test-utils": "^3.13.1",
"@types/jsonwebtoken": "^9.0.6",
"@types/node": "^20.14.9",
"changelogen": "^0.5.5",
"eslint": "^9.6.0",
"jsonwebtoken": "^9.0.2",
"nuxt": "^3.12.3",
"typescript": "latest",
"vitest": "^1.6.0",
Expand Down
5 changes: 4 additions & 1 deletion playground/pages/index.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<script setup lang="ts">
</script>

<template>
Expand All @@ -13,6 +12,10 @@
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Button
</button>

<UiKatButton>
TEST
</UiKatButton>
</div>
</div>
</template>
Expand Down
489 changes: 489 additions & 0 deletions pnpm-lock.yaml

Large diffs are not rendered by default.

110 changes: 80 additions & 30 deletions src/module.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import {defineNuxtModule, addPlugin, createResolver, extendPages, installModule, addServerHandler} from '@nuxt/kit'
import {
defineNuxtModule,
addPlugin,
createResolver,
extendPages,
installModule,
addServerHandler, addComponentsDir, addRouteMiddleware,
} from '@nuxt/kit'

/*
THIS MODULE IS THE CORE OF THE KATZENFRAMEWORK
Expand All @@ -7,52 +14,95 @@ ALSO AN EASY AND SIMPLE CMS WITH ITS OWN PATH AND LOCAL STORAGE
AND A BUILT IN AUTHENTICATION SYSTEM
*/

export interface ModuleOptions {}

export interface CmsUser {
name: string
password: string
}

export interface ModuleOptions {
users: CmsUser[],
secret: string
}

export default defineNuxtModule<ModuleOptions>({
meta: {
name: 'KatzenCore',
configKey: 'katzencore',
configKey: 'katzenCore',
},
// Default configuration options of the Nuxt module
defaults: {},
defaults: {
users: [
{
name: 'admin',
password: 'admin',
},
],
secret: 'secret',
},
async setup(_options, _nuxt) {
const { resolve } = createResolver(import.meta.url)

// Do not add the extension since the `.ts` will be transpiled to `.mjs` after `npm run prepack`
await installModules()
addPlugin(resolve('./runtime/plugin'))

// ADD BACKEND CMS PAGE
extendPages(
(pages) => {
pages.push({
name: 'katzen-preview',
path: '/preview',
file: resolve('runtime/pages/preview.vue'),
})
})

await installModule('@nuxtjs/tailwindcss', {
// module configuration
exposeConfig: true,
config: {
darkMode: 'class',
content: {
files: [
resolve('./runtime/components/**/*.{vue,mjs,ts}'),
resolve('./runtime/pages/**/*.{vue,mjs,ts}'),
resolve('./runtime/*.{mjs,js,ts}'),
],
},
},
})
const pageList = [
{
name: 'katzen-preview',
path: '/preview',
file: resolve('runtime/pages/preview.vue'),
},
{
name: 'katzen-cms-login',
path: '/preview-login',
file: resolve('runtime/pages/login.vue'),
},
]
pages.push(...pageList)
});

_nuxt.options.runtimeConfig.users = _options.users
_nuxt.options.runtimeConfig.secret = _options.secret

addRouteMiddleware({
name: 'auth',
path: resolve('./runtime/middleware/authentication'),
global: true,
})

//add backend server
addServerHandler(
{
route: '/katzen-core',
handler: resolve('./runtime/server/index.ts'),
}
route: '/login-cms',
handler: resolve('./runtime/server/login'),
},
)

// ADD FRONTEND COMPONENTS
await addComponentsDir({
path: resolve('runtime/components'),
})
},
})

const installModules = async () => {
const { resolve } = createResolver(import.meta.url)
await installModule('@nuxtjs/tailwindcss', {
// module configuration
exposeConfig: true,
config: {
darkMode: 'class',
content: {
files: [
resolve('./runtime/components/**/*.{vue,mjs,ts}'),
resolve('./runtime/pages/**/*.{vue,mjs,ts}'),
resolve('./runtime/*.{mjs,js,ts}'),
],
},
},
})

await installModule('@nuxt/image')
}
49 changes: 49 additions & 0 deletions src/runtime/components/ui/KatButton.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<script setup lang="ts">
import { computed, type PropType } from 'vue'
import { defineNuxtLink } from '#app'
const props = defineProps(
{
link: String,
katId: {
type: String,
default: 'not-set',
},
icon: {
type: String,
default: 'ArrowRight',
},
buttonType: {
type: String as PropType<'link' | 'button'>,
default: 'link',
},
color: {
type: String as PropType<'bg-ce-primary' | 'bg-ce-secondary'>,
default: 'bg-ce-primary',
},
},
)
const component = computed(() => {
if (props.buttonType === 'link') return defineNuxtLink({})
return 'button'
})
</script>

<template>
<component
:is="component"
:kat-e="katId"
kat-t="text"
class="rounded-full bg-red-400 py-3 px-4
text-center font-medium mt-3
flex flex-row items-center justify-center cursor-pointer
select-none transition-all hover:opacity-90 active:opacity-80"
:class="color"
:to="link"
>
<span>
<slot />
</span>
</component>
</template>
11 changes: 11 additions & 0 deletions src/runtime/components/ui/KatIcon.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script setup lang="ts">
</script>

<template>

</template>

<style scoped>
</style>
78 changes: 78 additions & 0 deletions src/runtime/components/ui/KatImage.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<script setup lang="ts">
import type { PropType } from 'vue'
defineProps(
{
src: {
type: String,
required: true,
},
alt: {
type: String,
default: '',
},
async: {
type: Boolean,
default: true,
},
loading: {
type: String as PropType<'lazy' | 'eager'>,
default: 'eager',
},
objectFit: {
type: String as PropType<'cover' | 'contain' | 'fill' | 'none' | 'scale-down'>,
default: 'cover',
},
showPlaceholder: {
type: Boolean,
default: true,
},
hideLoading: {
type: Boolean,
default: false,
},
sizes: {
type: String,
default: '300px md:600px lg:700px xl:800px',
},
},
)
const hideLoadingAnimation = ref(false)
const hidePlaceholder = () => {
setTimeout(() => {
hideLoadingAnimation.value = true
}, 50)
}
</script>

<template>
<div class="relative overflow-hidden select-none">
<div
v-if="!hideLoading"
class="absolute -z-10 top-0 left-0
bg-gray-100 rounded w-full h-full
transition-all duration-300"
:class="{ 'opacity-0': hideLoadingAnimation, 'animate-pulse': !hideLoadingAnimation }"
/>
<NuxtImg
ref="image"
:src="src"
:alt="alt"
:decoding="async ? 'async' : 'sync'"
:loading="loading"
:placeholder="showPlaceholder ? true:15"
:sizes="sizes"
densities="1x"
:placeholder-class="showPlaceholder? '' : 'opacity-0'"
class="w-full h-full z-10 max-h-full"
:style="{ objectFit }"
@load="hidePlaceholder"
/>
</div>
</template>

<style scoped>
</style>
11 changes: 11 additions & 0 deletions src/runtime/components/ui/KatText.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script setup lang="ts">
</script>

<template>

</template>

<style scoped>
</style>
24 changes: 24 additions & 0 deletions src/runtime/middleware/authentication.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export default defineNuxtRouteMiddleware(to => {

const checkAuth = () => {
const token = useCookie('token')
if(!token.value) return false
const jwt = require('jsonwebtoken');
return jwt.verify(token.value, useRuntimeConfig().secret)
}

console.log('Hello from the middleware!')
// skip middleware on client
if (import.meta.client) return
//if route is /preview-login and user is already logged in, redirect to /preview
if(to.path === '/preview-login') {
if(checkAuth()) {
return '/preview'
}
}
//route to is /preview
if(to.path !== '/preview') return;
if (!checkAuth()) {
return '/preview-login'
}
})
Loading

0 comments on commit 376a4f3

Please sign in to comment.