From d14488d2f2079daa288db2427ae3d89ffebb4964 Mon Sep 17 00:00:00 2001 From: Brian Rogers Date: Wed, 12 Aug 2026 14:14:09 -0600 Subject: [PATCH] committing everything before round 2 --- Makefile | 2 +- assets/avatars/system.png | Bin 0 -> 40703 bytes assets/avatars/zombie.png | Bin 0 -> 32124 bytes cmd/server/main.go | 4 +- internal/auth/handler.go | 21 ++ internal/auth/middleware.go | 3 + internal/auth/oauth.go | 4 + internal/auth/service.go | 16 ++ internal/db/database.sqlite | Bin 0 -> 172032 bytes internal/db/migrations/copy.sh | 40 ++++ internal/db/seeders/.gitignore | 2 + internal/issue/handler.go | 0 internal/issue/model.go | 0 internal/issue/repository.go | 0 internal/issue/service.go | 0 internal/project/handler.go | 0 internal/project/model.go | 0 internal/project/repository.go | 0 internal/project/service.go | 0 internal/server/router.go | 0 internal/server/server.go | 0 internal/user/handler.go | 0 internal/user/model.go | 0 internal/user/repository.go | 0 internal/user/service.go | 0 web/index.html | 86 ++++++-- web/src/api/user.ts | 21 ++ web/src/components/layout/AppNavbar.vue | 14 +- web/src/components/layout/AppSidebar.vue | 16 +- web/src/components/ui/Card.vue | 43 ++++ web/src/pages/auth/LoginPage.vue | 16 +- web/src/pages/dashboard/DashboardPage.vue | 26 +-- web/src/pages/profile/ProfilePage.vue | 238 ++++++++++++++++++++++ web/src/router/index.ts | 6 + web/src/stores/auth.ts | 3 + web/src/styles/main.css | 56 +++++ 36 files changed, 562 insertions(+), 55 deletions(-) create mode 100644 assets/avatars/system.png create mode 100644 assets/avatars/zombie.png create mode 100644 internal/auth/handler.go create mode 100644 internal/auth/middleware.go create mode 100644 internal/auth/oauth.go create mode 100644 internal/auth/service.go create mode 100644 internal/db/database.sqlite create mode 100644 internal/db/migrations/copy.sh create mode 100644 internal/db/seeders/.gitignore create mode 100644 internal/issue/handler.go create mode 100644 internal/issue/model.go create mode 100644 internal/issue/repository.go create mode 100644 internal/issue/service.go create mode 100644 internal/project/handler.go create mode 100644 internal/project/model.go create mode 100644 internal/project/repository.go create mode 100644 internal/project/service.go create mode 100644 internal/server/router.go create mode 100644 internal/server/server.go create mode 100644 internal/user/handler.go create mode 100644 internal/user/model.go create mode 100644 internal/user/repository.go create mode 100644 internal/user/service.go create mode 100644 web/src/api/user.ts create mode 100644 web/src/components/ui/Card.vue create mode 100644 web/src/pages/profile/ProfilePage.vue diff --git a/Makefile b/Makefile index 7a7bb12..bde898f 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ fmt: vet: fmt go vet ./... -build: vet +build: cd web && pnpm run build go build -v -o solopm-server ./cmd/server diff --git a/assets/avatars/system.png b/assets/avatars/system.png new file mode 100644 index 0000000000000000000000000000000000000000..5fb9f9ac52141cc31d0a94e2f41eedd325e47146 GIT binary patch literal 40703 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 literal 0 HcmV?d00001 diff --git a/assets/avatars/zombie.png b/assets/avatars/zombie.png new file mode 100644 index 0000000000000000000000000000000000000000..f81515278e319722896b01b31cda8bb6daedd59f GIT binary patch literal 32124 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 z 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 literal 0 HcmV?d00001 diff --git a/cmd/server/main.go b/cmd/server/main.go index c7b71a8..9484e2b 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -9,6 +9,8 @@ import ( "path/filepath" "time" + "solopm.com/solopm-server/auth" + "github.com/alexedwards/scs/v2" "github.com/joho/godotenv" ) @@ -22,7 +24,7 @@ func main() { } // handle authentication - sessionManager = scs.New() + sessionManager = scs.NewServerMux() sessionManager.Lifetime = 24 * time.Hour // handle frontend views diff --git a/internal/auth/handler.go b/internal/auth/handler.go new file mode 100644 index 0000000..aadb0ff --- /dev/null +++ b/internal/auth/handler.go @@ -0,0 +1,21 @@ +package auth + +import ( + + "github.com/alexedwards/scs/v2" + "golang.org/x/crypto/bcrypt" +) + +// remember, if anyone attempts to login as the system or zombie user, fail them. hard. + +// sessionManager needs to be figured out. do i inherit that from somewhere else? +// does it get associated with any other one like PHP's `session_open()` if i call it here? + + +func set(writer http.ResponseWriter, request *http.Request) { + sessionManager.Put(request.Context(), "sessionKey", "message to be passed around") +} + +func get(writer http.ResponseWriter, request *http.Request) String { + return sessionManager.GetString(request.Context(), "sessionKey") +} diff --git a/internal/auth/middleware.go b/internal/auth/middleware.go new file mode 100644 index 0000000..bf068dc --- /dev/null +++ b/internal/auth/middleware.go @@ -0,0 +1,3 @@ +package auth + +//import () diff --git a/internal/auth/oauth.go b/internal/auth/oauth.go new file mode 100644 index 0000000..9b3d757 --- /dev/null +++ b/internal/auth/oauth.go @@ -0,0 +1,4 @@ +package auth + +//import () + diff --git a/internal/auth/service.go b/internal/auth/service.go new file mode 100644 index 0000000..b7bb249 --- /dev/null +++ b/internal/auth/service.go @@ -0,0 +1,16 @@ +package auth + +import ( + "net/http" +) + + +func requireAuth(next http.Handler) http.Handler { + return http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) { + if !sessionManager.Exists(request.Context(), "userID") { + http.Redirect(writer, request, "/login", http.StatusSeeOther) + return + } + next.ServeHTTP(writer, request) + }) +} \ No newline at end of file diff --git a/internal/db/database.sqlite b/internal/db/database.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..ffc5f173b5974de09d694f960c49db91ab62b467 GIT binary patch literal 172032 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 "$down_file" + echo "DROP TABLE IF EXISTS ${quoted_text};" >> "$down_file" + tail -n 1 "$up_file" >> "$down_file" +done + +sed -i 's/\bCREATE\b/DROP/g' *.down.sql + +for file in *.sql; do + [ -f "$file" ] || continue + line3=$(sed -n '3p' "$file") + len=${#line3} + + if [ "$len" -lt 64 ]; then + needed=$((64 - len)) + dashes=$(printf '%*s' "$needed" | tr ' ' '-') + sed -i "3s/$/$dashes/" "$file" + fi +done + + + +for file in *.down.sql; do + [ -f "$file" ] || continue + first_line=$(head -n 1 "$file") + + if [[ "$first_line" == *".up.sql" ]]; then + sed -i '1s/\.up\.sql$/\.down\.sql/' "$file" + fi +done \ No newline at end of file diff --git a/internal/db/seeders/.gitignore b/internal/db/seeders/.gitignore new file mode 100644 index 0000000..d6b7ef3 --- /dev/null +++ b/internal/db/seeders/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/internal/issue/handler.go b/internal/issue/handler.go new file mode 100644 index 0000000..e69de29 diff --git a/internal/issue/model.go b/internal/issue/model.go new file mode 100644 index 0000000..e69de29 diff --git a/internal/issue/repository.go b/internal/issue/repository.go new file mode 100644 index 0000000..e69de29 diff --git a/internal/issue/service.go b/internal/issue/service.go new file mode 100644 index 0000000..e69de29 diff --git a/internal/project/handler.go b/internal/project/handler.go new file mode 100644 index 0000000..e69de29 diff --git a/internal/project/model.go b/internal/project/model.go new file mode 100644 index 0000000..e69de29 diff --git a/internal/project/repository.go b/internal/project/repository.go new file mode 100644 index 0000000..e69de29 diff --git a/internal/project/service.go b/internal/project/service.go new file mode 100644 index 0000000..e69de29 diff --git a/internal/server/router.go b/internal/server/router.go new file mode 100644 index 0000000..e69de29 diff --git a/internal/server/server.go b/internal/server/server.go new file mode 100644 index 0000000..e69de29 diff --git a/internal/user/handler.go b/internal/user/handler.go new file mode 100644 index 0000000..e69de29 diff --git a/internal/user/model.go b/internal/user/model.go new file mode 100644 index 0000000..e69de29 diff --git a/internal/user/repository.go b/internal/user/repository.go new file mode 100644 index 0000000..e69de29 diff --git a/internal/user/service.go b/internal/user/service.go new file mode 100644 index 0000000..e69de29 diff --git a/web/index.html b/web/index.html index ab2bbaf..472e5dc 100644 --- a/web/index.html +++ b/web/index.html @@ -1,17 +1,75 @@ - - - - - SoloPM + + + + - - - - - - -
- - + + + + + + + + + + + + + + + + + + + Page Title + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ diff --git a/web/src/api/user.ts b/web/src/api/user.ts new file mode 100644 index 0000000..81e6626 --- /dev/null +++ b/web/src/api/user.ts @@ -0,0 +1,21 @@ +import client from './client' +import type { User } from '@/stores/auth' + +export interface UpdateProfilePayload { + name: string + email: string + avatar_url?: string +} + +export interface ChangePasswordPayload { + current_password: string + new_password: string +} + +export const userApi = { + updateProfile: (payload: UpdateProfilePayload) => + client.put('/me', payload), + + changePassword: (payload: ChangePasswordPayload) => + client.put('/me/password', payload), +} diff --git a/web/src/components/layout/AppNavbar.vue b/web/src/components/layout/AppNavbar.vue index 146672e..ca56749 100644 --- a/web/src/components/layout/AppNavbar.vue +++ b/web/src/components/layout/AppNavbar.vue @@ -42,13 +42,19 @@
    -
  • +
  • + + {{ auth.user?.name ?? 'Account' }} +
diff --git a/web/src/components/layout/AppSidebar.vue b/web/src/components/layout/AppSidebar.vue index 74bae2d..4f21785 100644 --- a/web/src/components/layout/AppSidebar.vue +++ b/web/src/components/layout/AppSidebar.vue @@ -31,21 +31,9 @@
-
+
+ +
+ diff --git a/web/src/pages/auth/LoginPage.vue b/web/src/pages/auth/LoginPage.vue index be302ee..de90c08 100644 --- a/web/src/pages/auth/LoginPage.vue +++ b/web/src/pages/auth/LoginPage.vue @@ -2,7 +2,7 @@
-
+
@@ -15,24 +15,24 @@
- +
- +
@@ -41,7 +41,7 @@ @@ -56,7 +56,7 @@
Sign in with GitHub @@ -64,7 +64,7 @@ Sign in with Gitea diff --git a/web/src/pages/dashboard/DashboardPage.vue b/web/src/pages/dashboard/DashboardPage.vue index ad16ed0..79fa8dc 100644 --- a/web/src/pages/dashboard/DashboardPage.vue +++ b/web/src/pages/dashboard/DashboardPage.vue @@ -4,7 +4,7 @@
-
+
@@ -12,7 +12,7 @@
-
+
@@ -22,7 +22,7 @@
-
+
@@ -30,7 +30,7 @@
-
+
@@ -40,7 +40,7 @@
-
+
@@ -48,7 +48,7 @@
-
+
@@ -58,7 +58,7 @@
-
+
@@ -80,24 +80,24 @@
-
-
+
+
Activity

Recent updates

-
+

No activity yet.

-
-
+
+
Recent Projects

Your active projects

-
+

No projects yet.

diff --git a/web/src/pages/profile/ProfilePage.vue b/web/src/pages/profile/ProfilePage.vue new file mode 100644 index 0000000..150dd06 --- /dev/null +++ b/web/src/pages/profile/ProfilePage.vue @@ -0,0 +1,238 @@ + + + diff --git a/web/src/router/index.ts b/web/src/router/index.ts index 5e4e144..4918c1c 100644 --- a/web/src/router/index.ts +++ b/web/src/router/index.ts @@ -26,6 +26,12 @@ const router = createRouter({ component: () => import('@/pages/dashboard/DashboardPage.vue'), meta: { title: 'Dashboard' }, }, + { + path: '/profile', + name: 'profile', + component: () => import('@/pages/profile/ProfilePage.vue'), + meta: { title: 'Profile' }, + }, ], }) diff --git a/web/src/stores/auth.ts b/web/src/stores/auth.ts index e3a08d3..bdb1944 100644 --- a/web/src/stores/auth.ts +++ b/web/src/stores/auth.ts @@ -3,9 +3,12 @@ import { ref, computed } from 'vue' export interface User { id: number + username: string name: string email: string avatar_url?: string + is_admin: boolean + provider: string } export const useAuthStore = defineStore('auth', () => { diff --git a/web/src/styles/main.css b/web/src/styles/main.css index b5c61c9..62e3744 100644 --- a/web/src/styles/main.css +++ b/web/src/styles/main.css @@ -1,3 +1,59 @@ @tailwind base; @tailwind components; @tailwind utilities; + +@layer components { + /* ── Card ─────────────────────────────────────────────────────────── */ + .card { + @apply relative flex flex-col min-w-0 break-words bg-white shadow-soft-xl rounded-2xl bg-clip-border; + } + .card-header { + /* border-black/12.5 */ + @apply rounded-t-2xl border-b-0 border-solid p-6 pb-0; + } + .card-body { + @apply flex-auto p-6 pt-4; + } + + /* ── Buttons ──────────────────────────────────────────────────────── */ + /* Use display (inline-block / inline-flex) and sizing (px-* py-* w-*) as utilities alongside these. */ + .btn-primary { + @apply font-bold text-center text-white uppercase align-middle transition-all ease-in border-0 rounded-lg select-none shadow-soft-md bg-150 bg-x-25 leading-pro text-xs bg-gradient-to-tl from-purple-700 to-pink-500 hover:shadow-soft-2xl hover:scale-102 disabled:opacity-60 disabled:cursor-not-allowed disabled:hover:scale-100; + } + .btn-white { + @apply font-bold text-center text-slate-700 uppercase align-middle transition-all ease-in bg-white border border-solid border-gray-300 rounded-lg shadow-soft-sm leading-pro text-xs hover:shadow-soft-md hover:scale-102; + } + .btn-outlined { + @apply font-bold text-center uppercase align-middle transition-all bg-transparent border border-solid rounded-lg shadow-none cursor-pointer leading-pro text-xs border-fuchsia-500 ease-soft-in text-fuchsia-500 hover:border-fuchsia-500 active:bg-fuchsia-500 hover:bg-transparent hover:shadow-none; + } + + /* ── Forms ────────────────────────────────────────────────────────── */ + .form-label { + @apply mb-2 text-xs font-semibold text-slate-700 uppercase block; + } + .form-input { + @apply text-sm focus:shadow-soft-primary-outline ease-soft block w-full rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding py-2 px-3 text-gray-700 transition-all placeholder:text-gray-500 focus:border-fuchsia-300 focus:outline-none focus:transition-shadow; + } + + /* ── Sidebar nav ──────────────────────────────────────────────────── */ + /* .nav-item-active and .nav-item-inactive are modifiers applied alongside .nav-item */ + .nav-item { + @apply py-2.7 text-sm ease-nav-brand my-0 mx-4 flex items-center whitespace-nowrap rounded-lg px-4 font-semibold transition-colors; + } + .nav-item-active { + @apply shadow-soft-xl bg-white text-slate-700; + } + .nav-item-inactive { + @apply text-slate-500 hover:text-slate-700; + } + /* .nav-icon-active and .nav-icon-inactive are modifiers applied alongside .nav-icon */ + .nav-icon { + @apply mr-2 flex h-8 w-8 items-center justify-center rounded-lg bg-center stroke-0 text-center xl:p-2.5; + } + .nav-icon-active { + @apply bg-gradient-to-tl from-purple-700 to-pink-500 shadow-soft-2xl; + } + .nav-icon-inactive { + @apply bg-white shadow-soft-sm; + } +}