From 17eba9370a969d429505500aedb370821703514c Mon Sep 17 00:00:00 2001 From: Bernd Storath <999999bst@gmail.com> Date: Wed, 11 Sep 2024 15:47:54 +0200 Subject: [PATCH 01/16] improve gh actions --- .github/workflows/codeql.yml | 30 ++++++++++++++-------------- .github/workflows/deploy-nightly.yml | 5 ++++- .github/workflows/deploy.yml | 11 ++++++---- .github/workflows/stale.yml | 7 +++---- 4 files changed, 29 insertions(+), 24 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 31d962d0..191c33e2 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -2,9 +2,9 @@ name: "CodeQL" on: push: - branches: [ "master" ] + branches: ["master"] pull_request: - branches: [ "master" ] + branches: ["master"] schedule: - cron: "15 0 * * *" @@ -21,21 +21,21 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'javascript-typescript' ] + language: ["javascript-typescript"] steps: - - name: Checkout repository - uses: actions/checkout@v4 + - name: Checkout repository + uses: actions/checkout@v4 - - name: Initialize CodeQL - uses: github/codeql-action/init@v3 - with: - languages: ${{ matrix.language }} + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} - - name: Autobuild - uses: github/codeql-action/autobuild@v3 + - name: Autobuild + uses: github/codeql-action/autobuild@v3 - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v3 - with: - category: "/language:${{matrix.language}}" + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/deploy-nightly.yml b/.github/workflows/deploy-nightly.yml index 88404be3..03a75bba 100644 --- a/.github/workflows/deploy-nightly.yml +++ b/.github/workflows/deploy-nightly.yml @@ -54,4 +54,7 @@ jobs: git config --global user.name 'Docs Deploy Bot' git config --global user.email 'docs.deploy@users.noreply.github.com' - name: Build Docs Website - run: mike deploy --push nightly + run: | + cd docs + git fetch origin gh-pages --depth=1 + mike deploy --push --update-aliases nightly diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index aea89c16..321c72e1 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -3,8 +3,8 @@ name: Build & Publish Latest on: workflow_dispatch: push: - branches: - - master + tags: + - "v*" jobs: deploy: @@ -27,7 +27,7 @@ jobs: - name: Docker meta id: meta - uses: docker/metadata-action@v3 + uses: docker/metadata-action@v5 with: images: | ghcr.io/wg-easy/wg-easy @@ -67,4 +67,7 @@ jobs: git config --global user.name 'Docs Deploy Bot' git config --global user.email 'docs.deploy@users.noreply.github.com' - name: Build Docs Website - run: mike deploy --push --update-aliases ${{ github.ref_name }} latest + run: | + cd docs + git fetch origin gh-pages --depth=1 + mike deploy --push --update-aliases ${{ github.ref_name }} latest diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 868fa296..17af45a9 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -8,11 +8,10 @@ name: Mark stale issues and pull requests on: workflow_dispatch: schedule: - - cron: '*/5 * * * *' + - cron: "*/5 * * * *" jobs: stale: - runs-on: ubuntu-latest if: github.repository_owner == 'wg-easy' permissions: @@ -20,8 +19,8 @@ jobs: pull-requests: write steps: - - uses: actions/stale@v9 - with: + - uses: actions/stale@v9 + with: days-before-issue-stale: 30 days-before-issue-close: 14 stale-issue-label: "stale" From cde22fc6cb67d82c2036a43caf037b0458699e2d Mon Sep 17 00:00:00 2001 From: tetuaoro <65575727+tetuaoro@users.noreply.github.com> Date: Wed, 11 Sep 2024 16:04:27 +0200 Subject: [PATCH 02/16] Setup UI (#1392) * update: setup ui page * rebase * remove script addition --- src/app/layouts/Header.vue | 2 +- src/app/pages/setup.vue | 51 ++++++++++++++++++++++++++++---------- src/locales/en.json | 11 ++++++++ src/locales/fr.json | 11 ++++++++ 4 files changed, 61 insertions(+), 14 deletions(-) diff --git a/src/app/layouts/Header.vue b/src/app/layouts/Header.vue index 3ea58a0d..ccca6357 100644 --- a/src/app/layouts/Header.vue +++ b/src/app/layouts/Header.vue @@ -8,7 +8,7 @@ " >

-
+

@@ -7,40 +7,59 @@ WireGuard

-

Welcome to your first setup of wg-easy !

-

Please first enter an admin username and a strong password.

-
+

+ {{ $t('setup.welcome') }} +

+

{{ $t('setup.msg') }}

+
- + + {{ + $t('setup.usernameCondition') + }}
- + + {{ + $t('setup.passwordCondition') + }}
- - + +
- + > + {{ $t('setup.submitBtn') }} +
@@ -61,6 +82,9 @@ const username = ref(null); const password = ref(null); const authStore = useAuthStore(); +const errorCU = ref(false); +const errorPWD = ref(false); + async function newAccount(e: Event) { e.preventDefault(); @@ -74,6 +98,7 @@ async function newAccount(e: Event) { } catch (error) { if (error instanceof Error) { // TODO: replace alert with actual ui error message + // TODO: also use errorCU & errorPWD to show prompt error alert(error.message || error.toString()); } } diff --git a/src/locales/en.json b/src/locales/en.json index 77cae6ff..ff9f3612 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -1,4 +1,15 @@ { + "setup": { + "welcome": "Welcome to your first setup of wg-easy !", + "msg": "Please first enter an admin username and a strong secure password. This information will be used to log in to your administration panel.", + "newPassword": "New Password", + "accept": "I accept the condition", + "submitBtn": "Create admin account", + "usernameCondition": "The username must contain at least 8 characters.", + "passwordCondition": "The password must contain at least 12 characters, including 1 uppercase letter, 1 lowercase letter, 1 digit, and 1 special character.", + "usernamePlaceholder": "Administrator", + "passwordPlaceholder": "Strong password" + }, "name": "Name", "username": "Username", "password": "Password", diff --git a/src/locales/fr.json b/src/locales/fr.json index 747a7aac..444595c3 100644 --- a/src/locales/fr.json +++ b/src/locales/fr.json @@ -1,4 +1,15 @@ { + "setup": { + "welcome": "Bienvenue à la page de configuration de votre wg-easy !", + "msg": "Veuillez renseigner votre nom d'utilisateur et votre mot de passe. Ces informations seront utilisées pour vous connecter à votre page d'administration.", + "newPassword": "Nouveau mot de passe", + "accept": "J'accepte les conditions d'utilisation", + "submitBtn": "Créer un nouveau compte", + "usernameCondition": "Le nom d'utilisateur doit contenir au moins 8 caractères.", + "passwordCondition": "Le mot de passe doit contenir au moins 12 caractères dont 1 majuscule, 1 minuscule, 1 chiffre et 1 caractère spécial.", + "usernamePlaceholder": "Administrateur", + "passwordPlaceholder": "Mot de passe sapau" + }, "name": "Nom", "password": "Mot de passe", "signIn": "Se Connecter", From d758216f55ca86c3c1fab7d6bd85ebaafdf72ea7 Mon Sep 17 00:00:00 2001 From: Bernd Storath <999999bst@gmail.com> Date: Wed, 11 Sep 2024 07:36:13 +0200 Subject: [PATCH 03/16] add admin panel --- src/app/layouts/Header.vue | 2 +- src/app/pages/admin/index.vue | 5 +++++ src/app/stores/auth.ts | 14 ++++---------- src/app/utils/api.ts | 3 +-- src/server/api/session.get.ts | 19 ++++++++++++++++--- src/server/api/session.post.ts | 3 +-- src/server/middleware/auth.ts | 22 ++++++++++++++++++++-- src/server/utils/session.ts | 2 +- 8 files changed, 49 insertions(+), 21 deletions(-) create mode 100644 src/app/pages/admin/index.vue diff --git a/src/app/layouts/Header.vue b/src/app/layouts/Header.vue index ccca6357..d1e5827b 100644 --- a/src/app/layouts/Header.vue +++ b/src/app/layouts/Header.vue @@ -52,7 +52,7 @@ /> diff --git a/src/app/pages/admin/index.vue b/src/app/pages/admin/index.vue new file mode 100644 index 00000000..041fe622 --- /dev/null +++ b/src/app/pages/admin/index.vue @@ -0,0 +1,5 @@ + + + diff --git a/src/app/stores/auth.ts b/src/app/stores/auth.ts index 403cb542..e9bf3a31 100644 --- a/src/app/stores/auth.ts +++ b/src/app/stores/auth.ts @@ -1,6 +1,4 @@ export const useAuthStore = defineStore('Auth', () => { - const requiresPassword = ref(true); - /** * @throws if unsuccessful */ @@ -13,8 +11,7 @@ export const useAuthStore = defineStore('Auth', () => { * @throws if unsuccessful */ async function login(username: string, password: string, remember: boolean) { - const response = await api.createSession({ username, password, remember }); - requiresPassword.value = response.requiresPassword; + await api.createSession({ username, password, remember }); return true as const; } @@ -26,13 +23,10 @@ export const useAuthStore = defineStore('Auth', () => { return response.success; } - /** - * @throws if unsuccessful - */ async function update() { - const session = await api.getSession(); - requiresPassword.value = session.requiresPassword; + // store role etc + await api.getSession(); } - return { requiresPassword, login, logout, update, signup }; + return { login, logout, update, signup }; }); diff --git a/src/app/utils/api.ts b/src/app/utils/api.ts index fcfa99a1..feb21bc7 100644 --- a/src/app/utils/api.ts +++ b/src/app/utils/api.ts @@ -12,8 +12,7 @@ class API { } async getSession() { - // TODO?: use useFetch - return $fetch('/api/session', { + return useFetch('/api/session', { method: 'get', }); } diff --git a/src/server/api/session.get.ts b/src/server/api/session.get.ts index 9aa91658..7a97cc73 100644 --- a/src/server/api/session.get.ts +++ b/src/server/api/session.get.ts @@ -1,9 +1,22 @@ export default defineEventHandler(async (event) => { const session = await useWGSession(event); - const authenticated = session.data.authenticated; + + if (!session.data.userId) { + throw createError({ + statusCode: 401, + statusMessage: 'Not logged in', + }); + } + const user = await Database.user.findById(session.data.userId); + if (!user) { + throw createError({ + statusCode: 404, + statusMessage: 'Not found in Database', + }); + } return { - requiresPassword: true, - authenticated, + role: user.role, + username: user.username, }; }); diff --git a/src/server/api/session.post.ts b/src/server/api/session.post.ts index ea9e1a36..a15c9675 100644 --- a/src/server/api/session.post.ts +++ b/src/server/api/session.post.ts @@ -34,12 +34,11 @@ export default defineEventHandler(async (event) => { }; } - const session = await useSession(event, { + const session = await useSession(event, { ...system.sessionConfig, }); const data = await session.update({ - authenticated: true, userId: user.id, }); diff --git a/src/server/middleware/auth.ts b/src/server/middleware/auth.ts index ce90ece2..fe37d19b 100644 --- a/src/server/middleware/auth.ts +++ b/src/server/middleware/auth.ts @@ -1,14 +1,32 @@ export default defineEventHandler(async (event) => { const url = getRequestURL(event); const session = await useWGSession(event); + if (url.pathname === '/login') { - if (session.data.authenticated) { + if (session.data.userId) { return sendRedirect(event, '/', 302); } } + if (url.pathname === '/') { - if (!session.data.authenticated) { + if (!session.data.userId) { return sendRedirect(event, '/login', 302); } } + + if (url.pathname === '/admin') { + if (!session.data.userId) { + return sendRedirect(event, '/login', 302); + } + const user = await Database.user.findById(session.data.userId); + if (!user) { + return sendRedirect(event, '/login', 302); + } + if (!user.enabled || user.role !== 'ADMIN') { + throw createError({ + statusCode: 403, + statusMessage: 'Not allowed to access Admin Panel', + }); + } + } }); diff --git a/src/server/utils/session.ts b/src/server/utils/session.ts index bb7e4aa0..bb0ec9c8 100644 --- a/src/server/utils/session.ts +++ b/src/server/utils/session.ts @@ -1,7 +1,7 @@ import type { H3Event } from 'h3'; export type WGSession = { - authenticated: boolean; + userId: string; }; export async function useWGSession(event: H3Event) { From 6ecc3bb1e7a2b3a8f8517a6f6161f21c87980ea3 Mon Sep 17 00:00:00 2001 From: Bernd Storath <999999bst@gmail.com> Date: Wed, 11 Sep 2024 08:17:35 +0200 Subject: [PATCH 04/16] basic user menu and admin page --- src/app/components/ui/UserMenu.vue | 90 ++++++++++++++++++++++++++++++ src/app/layouts/Header.vue | 23 +------- src/app/pages/admin/index.vue | 5 +- src/app/pages/index.vue | 2 + src/app/stores/auth.ts | 11 +++- src/server/api/session.get.ts | 1 + src/server/middleware/session.ts | 4 +- 7 files changed, 109 insertions(+), 27 deletions(-) create mode 100644 src/app/components/ui/UserMenu.vue diff --git a/src/app/components/ui/UserMenu.vue b/src/app/components/ui/UserMenu.vue new file mode 100644 index 00000000..debecc0a --- /dev/null +++ b/src/app/components/ui/UserMenu.vue @@ -0,0 +1,90 @@ + + + diff --git a/src/app/layouts/Header.vue b/src/app/layouts/Header.vue index d1e5827b..50625aad 100644 --- a/src/app/layouts/Header.vue +++ b/src/app/layouts/Header.vue @@ -51,14 +51,7 @@ class="w-5 h-5 peer fill-gray-400 peer-checked:fill-gray-600 dark:fill-neutral-600 peer-checked:dark:fill-neutral-400 group-hover:dark:fill-neutral-500 transition" /> - - {{ $t('logout') }} - - +
@@ -86,7 +79,6 @@ diff --git a/src/app/pages/admin/index.vue b/src/app/pages/admin/index.vue index 041fe622..3cbcfd8a 100644 --- a/src/app/pages/admin/index.vue +++ b/src/app/pages/admin/index.vue @@ -2,4 +2,7 @@
Admin Area
- + diff --git a/src/app/pages/index.vue b/src/app/pages/index.vue index 3f8ef5e2..ca079a0e 100644 --- a/src/app/pages/index.vue +++ b/src/app/pages/index.vue @@ -54,6 +54,8 @@ const intervalId = ref(null); clientsStore.refresh(); onMounted(() => { + // to avoid console spam + return; // TODO?: replace with websocket or similar intervalId.value = setInterval(() => { clientsStore diff --git a/src/app/stores/auth.ts b/src/app/stores/auth.ts index e9bf3a31..ad359c0b 100644 --- a/src/app/stores/auth.ts +++ b/src/app/stores/auth.ts @@ -1,4 +1,10 @@ export const useAuthStore = defineStore('Auth', () => { + const userData = ref(); + /** * @throws if unsuccessful */ @@ -25,8 +31,9 @@ export const useAuthStore = defineStore('Auth', () => { async function update() { // store role etc - await api.getSession(); + const { data: response } = await api.getSession(); + userData.value = response.value; } - return { login, logout, update, signup }; + return { userData, login, logout, update, signup }; }); diff --git a/src/server/api/session.get.ts b/src/server/api/session.get.ts index 7a97cc73..9f559c08 100644 --- a/src/server/api/session.get.ts +++ b/src/server/api/session.get.ts @@ -18,5 +18,6 @@ export default defineEventHandler(async (event) => { return { role: user.role, username: user.username, + name: user.name, }; }); diff --git a/src/server/middleware/session.ts b/src/server/middleware/session.ts index 3611aaae..5a8c063c 100644 --- a/src/server/middleware/session.ts +++ b/src/server/middleware/session.ts @@ -12,8 +12,8 @@ export default defineEventHandler(async (event) => { } const system = await Database.system.get(); - const session = await getSession(event, system.sessionConfig); - if (session.id && session.data.authenticated) { + const session = await getSession(event, system.sessionConfig); + if (session.id && session.data.userId) { return; } From 2db9133a1482cf8c913fbeef8ebd13f700dd95c1 Mon Sep 17 00:00:00 2001 From: Bernd Storath <999999bst@gmail.com> Date: Wed, 11 Sep 2024 08:41:06 +0200 Subject: [PATCH 05/16] make usable admin panel --- src/app/pages/admin.vue | 51 +++++++++++++++++++++++++++++++++ src/app/pages/admin/clients.vue | 34 ++++++++++++++++++++++ src/app/pages/admin/index.vue | 7 ++--- src/app/pages/admin/server.vue | 34 ++++++++++++++++++++++ src/app/pages/admin/user.vue | 34 ++++++++++++++++++++++ src/server/middleware/auth.ts | 2 +- 6 files changed, 156 insertions(+), 6 deletions(-) create mode 100644 src/app/pages/admin.vue create mode 100644 src/app/pages/admin/clients.vue create mode 100644 src/app/pages/admin/server.vue create mode 100644 src/app/pages/admin/user.vue diff --git a/src/app/pages/admin.vue b/src/app/pages/admin.vue new file mode 100644 index 00000000..0ac27a88 --- /dev/null +++ b/src/app/pages/admin.vue @@ -0,0 +1,51 @@ + + + diff --git a/src/app/pages/admin/clients.vue b/src/app/pages/admin/clients.vue new file mode 100644 index 00000000..53a4b11b --- /dev/null +++ b/src/app/pages/admin/clients.vue @@ -0,0 +1,34 @@ + + + diff --git a/src/app/pages/admin/index.vue b/src/app/pages/admin/index.vue index 3cbcfd8a..d4a40441 100644 --- a/src/app/pages/admin/index.vue +++ b/src/app/pages/admin/index.vue @@ -1,8 +1,5 @@ - + diff --git a/src/app/pages/admin/server.vue b/src/app/pages/admin/server.vue new file mode 100644 index 00000000..53a4b11b --- /dev/null +++ b/src/app/pages/admin/server.vue @@ -0,0 +1,34 @@ + + + diff --git a/src/app/pages/admin/user.vue b/src/app/pages/admin/user.vue new file mode 100644 index 00000000..53a4b11b --- /dev/null +++ b/src/app/pages/admin/user.vue @@ -0,0 +1,34 @@ + + + diff --git a/src/server/middleware/auth.ts b/src/server/middleware/auth.ts index fe37d19b..7ab156f0 100644 --- a/src/server/middleware/auth.ts +++ b/src/server/middleware/auth.ts @@ -14,7 +14,7 @@ export default defineEventHandler(async (event) => { } } - if (url.pathname === '/admin') { + if (url.pathname.startsWith('/admin')) { if (!session.data.userId) { return sendRedirect(event, '/login', 302); } From 64b4fe1f401a462f2c242ddb38433e50e9eb7961 Mon Sep 17 00:00:00 2001 From: Bernd Storath <999999bst@gmail.com> Date: Wed, 11 Sep 2024 12:44:20 +0200 Subject: [PATCH 06/16] add radix vue, improve ui --- src/app/components/ui/UserMenu.vue | 134 ++++++++++++++--------------- src/app/layouts/Header.vue | 22 ++--- src/app/pages/admin.vue | 33 +++---- src/app/pages/admin/clients.vue | 34 -------- src/app/pages/admin/features.vue | 63 ++++++++++++++ src/app/pages/admin/index.vue | 9 +- src/app/pages/admin/server.vue | 34 -------- src/app/pages/admin/user.vue | 34 -------- src/nuxt.config.ts | 1 + src/package.json | 1 + src/pnpm-lock.yaml | 134 +++++++++++++++++++++++++++++ 11 files changed, 301 insertions(+), 198 deletions(-) delete mode 100644 src/app/pages/admin/clients.vue create mode 100644 src/app/pages/admin/features.vue delete mode 100644 src/app/pages/admin/server.vue delete mode 100644 src/app/pages/admin/user.vue diff --git a/src/app/components/ui/UserMenu.vue b/src/app/components/ui/UserMenu.vue index debecc0a..43d79190 100644 --- a/src/app/components/ui/UserMenu.vue +++ b/src/app/components/ui/UserMenu.vue @@ -1,80 +1,70 @@ diff --git a/src/app/layouts/Header.vue b/src/app/layouts/Header.vue index 50625aad..7c9b03a4 100644 --- a/src/app/layouts/Header.vue +++ b/src/app/layouts/Header.vue @@ -7,16 +7,18 @@ : 'flex flex-col-reverse xxs:flex-row flex-auto items-center gap-3' " > -

- WireGuard -

+ +

+ WireGuard +

+