✨ feat (auth): implement global authentication middleware
This commit is contained in:
@@ -12,15 +12,15 @@ RSSA - Front End
|
||||
## Directory Structure for `app/`
|
||||
- `app.vue`: Main layout
|
||||
- `components` : Contains all reusable UI components.
|
||||
- `components/flows` : Entry point for business logic and workflows. Pages or routes call these flow components to handle API requests and process application logic
|
||||
- `components/app` : View-layer components that manage and present data. These are used within `flows/` to render or handle specific parts of the UI, and return results back to the flow
|
||||
- `components/flow` : Entry point for business logic and workflows. Pages or routes call these flow components to handle API requests and process application logic
|
||||
- `components/app` : View-layer components that manage and present data. These are used within `flow/` to render or handle specific parts of the UI, and return results back to the flow
|
||||
- `components/pub` : Public/shared components used across different parts of the app.
|
||||
- `composables` : Contains reusable logic and utility functions (e.g. composables, hooks)..
|
||||
- `layouts` : Reusable UI layout patterns used across pages.
|
||||
|
||||
## Directory Structure for `app/pages`
|
||||
- `pages/auth` : Authentication related pages.
|
||||
- `pages/(features)` : Grouped feature modules that reflect specific business flows or domains.
|
||||
- `pages/(features)` : Grouped feature modules that reflect specific business flow or domains.
|
||||
|
||||
## Directory Structure for `server/`
|
||||
- `server/api` : API or proxy requests
|
||||
@@ -37,13 +37,13 @@ The basic development workflow follows these steps:
|
||||
- Keep components pure, avoid making HTTP requests directly within them.
|
||||
- They receive data via props and emit events upward.
|
||||
|
||||
### Business Logic in `components/flows`
|
||||
### Business Logic in `components/flow`
|
||||
- This layer connects the UI with the logic (API calls, validations, navigation).
|
||||
- It composes components from `components/app/`, `components/pub/`, and other flows.
|
||||
- It composes components from `components/app/`, `components/pub/`, and other flow.
|
||||
- Also responsible for managing state, side effects, and interactions.
|
||||
|
||||
### Create Pages in `pages/`
|
||||
- Pages load the appropriate flow from `components/flows/`.
|
||||
- Pages load the appropriate flow from `components/flow/`.
|
||||
- They do not contain UI or logic directly, just route level layout or guards.
|
||||
|
||||
## Git Workflows
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
export default defineNuxtRouteMiddleware((to) => {
|
||||
const { $pinia } = useNuxtApp()
|
||||
|
||||
if (import.meta.client) {
|
||||
const userStore = useUserStore($pinia)
|
||||
|
||||
console.log('currRole', userStore.userRole)
|
||||
console.log('isAuth', userStore.isAuthenticated)
|
||||
if (!userStore.isAuthenticated) {
|
||||
return navigateTo('/auth/login')
|
||||
}
|
||||
|
||||
const allowedRoles = to.meta.roles as string[] | undefined
|
||||
if (allowedRoles && !allowedRoles.includes(userStore.userRole)) {
|
||||
return navigateTo('/unauthorized')
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -1,7 +0,0 @@
|
||||
export default defineNuxtRouteMiddleware((to, from) => {
|
||||
// TODO: change this to actual api
|
||||
const user = true
|
||||
if (!user) {
|
||||
return navigateTo('/auth/login')
|
||||
}
|
||||
})
|
||||
@@ -1,3 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
roles: ['sys', 'doc'],
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>detail pasien</div>
|
||||
</template>
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
roles: ['sys', 'doc'],
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>edit pasien</div>
|
||||
</template>
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
roles: ['sys', 'doc'],
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<FlowPatientAdd />
|
||||
</template>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
roles: ['system', 'doctor'],
|
||||
roles: ['sys', 'doc'],
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
Vendored
+16
@@ -0,0 +1,16 @@
|
||||
// app/types/index.d.ts
|
||||
import type { Pinia } from 'pinia'
|
||||
|
||||
declare module '#app' {
|
||||
interface NuxtApp {
|
||||
$pinia: Pinia
|
||||
}
|
||||
}
|
||||
|
||||
declare module '@vue/runtime-core' {
|
||||
interface ComponentCustomProperties {
|
||||
$pinia: Pinia
|
||||
}
|
||||
}
|
||||
|
||||
export {}
|
||||
Vendored
-9
@@ -1,9 +0,0 @@
|
||||
declare module '#app' {
|
||||
interface NuxtApp {}
|
||||
}
|
||||
|
||||
declare module 'vue' {
|
||||
interface ComponentCustomProperties {}
|
||||
}
|
||||
|
||||
export {}
|
||||
@@ -21,6 +21,7 @@
|
||||
"embla-carousel": "^8.5.2",
|
||||
"embla-carousel-vue": "^8.5.2",
|
||||
"h3": "^1.15.4",
|
||||
"pinia": "^3.0.3",
|
||||
"pinia-plugin-persistedstate": "^4.4.1",
|
||||
"reka-ui": "^2.4.1"
|
||||
},
|
||||
|
||||
Generated
+20
-13
@@ -29,9 +29,12 @@ dependencies:
|
||||
h3:
|
||||
specifier: ^1.15.4
|
||||
version: 1.15.4
|
||||
pinia:
|
||||
specifier: ^3.0.3
|
||||
version: 3.0.3(typescript@5.9.2)(vue@3.5.18)
|
||||
pinia-plugin-persistedstate:
|
||||
specifier: ^4.4.1
|
||||
version: 4.4.1(@pinia/nuxt@0.5.5)
|
||||
version: 4.4.1(@pinia/nuxt@0.5.5)(pinia@3.0.3)
|
||||
reka-ui:
|
||||
specifier: ^2.4.1
|
||||
version: 2.4.1(typescript@5.9.2)(vue@3.5.18)
|
||||
@@ -4323,7 +4326,6 @@ packages:
|
||||
resolution: {integrity: sha512-lwOnNBH2e7x1fIIbVT7yF5D+YWhqELm55/4ZKf45R9T8r9dE2AIOy8HKjfqzGsoTHFbWbr337O4E0A0QADnjBg==}
|
||||
dependencies:
|
||||
'@vue/devtools-kit': 7.7.7
|
||||
dev: true
|
||||
|
||||
/@vue/devtools-core@7.7.7(vite@7.1.1)(vue@3.5.18):
|
||||
resolution: {integrity: sha512-9z9TLbfC+AjAi1PQyWX+OErjIaJmdFlbDHcD+cAMYKY6Bh5VlsAtCeGyRMrXwIlMEQPukvnWt3gZBLwTAIMKzQ==}
|
||||
@@ -4351,13 +4353,11 @@ packages:
|
||||
perfect-debounce: 1.0.0
|
||||
speakingurl: 14.0.1
|
||||
superjson: 2.2.2
|
||||
dev: true
|
||||
|
||||
/@vue/devtools-shared@7.7.7:
|
||||
resolution: {integrity: sha512-+udSj47aRl5aKb0memBvcUG9koarqnxNM5yjuREvqwK6T3ap4mn3Zqqc17QrBFTqSMjr3HK1cvStEZpMDpfdyw==}
|
||||
dependencies:
|
||||
rfdc: 1.4.1
|
||||
dev: true
|
||||
|
||||
/@vue/language-core@2.2.12(typescript@5.9.2):
|
||||
resolution: {integrity: sha512-IsGljWbKGU1MZpBPN+BvPAdr55YPkj2nB/TBNGNC32Vy2qLG25DYu/NBN2vNtZqdRbTRjaoYrahLrToim2NanA==}
|
||||
@@ -4909,7 +4909,6 @@ packages:
|
||||
|
||||
/birpc@2.5.0:
|
||||
resolution: {integrity: sha512-VSWO/W6nNQdyP520F1mhf+Lc2f8pjGQOtoHHm7Ze8Go1kX7akpVIrtTa0fn+HB0QJEDVacl6aO08YE0PgXfdnQ==}
|
||||
dev: true
|
||||
|
||||
/boolbase@1.0.0:
|
||||
resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
|
||||
@@ -5299,7 +5298,6 @@ packages:
|
||||
engines: {node: '>=12.13'}
|
||||
dependencies:
|
||||
is-what: 4.1.16
|
||||
dev: true
|
||||
|
||||
/copy-file@11.0.0:
|
||||
resolution: {integrity: sha512-mFsNh/DIANLqFt5VHZoGirdg7bK5+oTWlhnGu6tgRhzBlnEKWaPX2xrFaLltii/6rmhqFMJqffUgknuRdpYlHw==}
|
||||
@@ -7342,7 +7340,6 @@ packages:
|
||||
|
||||
/hookable@5.5.3:
|
||||
resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
|
||||
dev: true
|
||||
|
||||
/hosted-git-info@7.0.2:
|
||||
resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==}
|
||||
@@ -7621,7 +7618,6 @@ packages:
|
||||
/is-what@4.1.16:
|
||||
resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==}
|
||||
engines: {node: '>=12.13'}
|
||||
dev: true
|
||||
|
||||
/is-wsl@2.2.0:
|
||||
resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==}
|
||||
@@ -8558,7 +8554,6 @@ packages:
|
||||
|
||||
/mitt@3.0.1:
|
||||
resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==}
|
||||
dev: true
|
||||
|
||||
/mkdirp@3.0.1:
|
||||
resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==}
|
||||
@@ -9369,7 +9364,7 @@ packages:
|
||||
resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
/pinia-plugin-persistedstate@4.4.1(@pinia/nuxt@0.5.5):
|
||||
/pinia-plugin-persistedstate@4.4.1(@pinia/nuxt@0.5.5)(pinia@3.0.3):
|
||||
resolution: {integrity: sha512-lmuMPpXla2zJKjxEq34e1E9P9jxkWEhcVwwioCCE0izG45kkTOvQfCzvwhW3i38cvnaWC7T1eRdkd15Re59ldw==}
|
||||
peerDependencies:
|
||||
'@nuxt/kit': '>=3.0.0'
|
||||
@@ -9387,6 +9382,7 @@ packages:
|
||||
deep-pick-omit: 1.2.1
|
||||
defu: 6.1.4
|
||||
destr: 2.0.5
|
||||
pinia: 3.0.3(typescript@5.9.2)(vue@3.5.18)
|
||||
dev: false
|
||||
|
||||
/pinia@2.3.1(typescript@5.9.2)(vue@3.5.18):
|
||||
@@ -9405,6 +9401,20 @@ packages:
|
||||
transitivePeerDependencies:
|
||||
- '@vue/composition-api'
|
||||
|
||||
/pinia@3.0.3(typescript@5.9.2)(vue@3.5.18):
|
||||
resolution: {integrity: sha512-ttXO/InUULUXkMHpTdp9Fj4hLpD/2AoJdmAbAeW2yu1iy1k+pkFekQXw5VpC0/5p51IOR/jDaDRfRWRnMMsGOA==}
|
||||
peerDependencies:
|
||||
typescript: '>=4.4.4'
|
||||
vue: ^2.7.0 || ^3.5.11
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@vue/devtools-api': 7.7.7
|
||||
typescript: 5.9.2
|
||||
vue: 3.5.18(typescript@5.9.2)
|
||||
dev: false
|
||||
|
||||
/pkg-types@1.3.1:
|
||||
resolution: {integrity: sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==}
|
||||
dependencies:
|
||||
@@ -10151,7 +10161,6 @@ packages:
|
||||
|
||||
/rfdc@1.4.1:
|
||||
resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==}
|
||||
dev: true
|
||||
|
||||
/robust-predicates@3.0.2:
|
||||
resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==}
|
||||
@@ -10489,7 +10498,6 @@ packages:
|
||||
/speakingurl@14.0.1:
|
||||
resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: true
|
||||
|
||||
/stable-hash-x@0.2.0:
|
||||
resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==}
|
||||
@@ -10626,7 +10634,6 @@ packages:
|
||||
engines: {node: '>=16'}
|
||||
dependencies:
|
||||
copy-anything: 3.0.5
|
||||
dev: true
|
||||
|
||||
/supports-color@10.1.0:
|
||||
resolution: {integrity: sha512-GBuewsPrhJPftT+fqDa9oI/zc5HNsG9nREqwzoSFDOIqf0NggOZbHQj2TE1P1CDJK8ZogFnlZY9hWoUiur7I/A==}
|
||||
|
||||
Reference in New Issue
Block a user