diff --git a/.env.example b/.env.example index be5ef94..c36fed7 100644 --- a/.env.example +++ b/.env.example @@ -5,5 +5,10 @@ DATABASE_URL= ENCRYPTION_KEY="" # OAuth client +OAUTH_ENABLED=github,gitlab + GITHUB_CLIENT_ID= GITHUB_CLIENT_SECRET= + +GITLAB_CLIENT_ID= +GITLAB_CLIENT_SECRET= diff --git a/frontend/pages/auth/components/login-gitlab.tsx b/frontend/pages/auth/components/login-gitlab.tsx new file mode 100644 index 0000000..aad4b2f --- /dev/null +++ b/frontend/pages/auth/components/login-gitlab.tsx @@ -0,0 +1,43 @@ +import React, { useEffect, useMemo } from "react"; +import { useAuthRequest } from "expo-auth-session"; +import { Button } from "tamagui"; +import { useOAuthCallback } from "../hooks"; +import { useServerConfig } from "@/hooks/useServerConfig"; + +const LoginGitlabButton = () => { + const { data: clientId } = useServerConfig("gitlab_client_id"); + const discovery = useMemo(() => { + return { + authorizationEndpoint: "https://gitlab.com/oauth/authorize", + tokenEndpoint: "https://gitlab.com/oauth/token", + revocationEndpoint: "https://gitlab.com/oauth/revoke", + }; + }, [clientId]); + const oauth = useOAuthCallback("gitlab"); + + const [request, response, promptAsync] = useAuthRequest( + { + clientId, + scopes: ["read_user"], + // redirectUri: makeRedirectUri({ scheme: appConfig.scheme }), + redirectUri: "http://localhost:8081", + }, + discovery + ); + + useEffect(() => { + if (response?.type === "success") { + const { code } = response.params; + const verifier = request?.codeVerifier; + oauth.mutate({ code, verifier }); + } + }, [response]); + + return ( + + ); +}; + +export default LoginGitlabButton; diff --git a/frontend/pages/auth/hooks.ts b/frontend/pages/auth/hooks.ts index 7119a31..4e5784d 100644 --- a/frontend/pages/auth/hooks.ts +++ b/frontend/pages/auth/hooks.ts @@ -1,4 +1,4 @@ -import { useMutation } from "@tanstack/react-query"; +import { useMutation, useQuery } from "@tanstack/react-query"; import { loginResultSchema, LoginSchema, @@ -45,8 +45,8 @@ export const useRegisterMutation = () => { export const useOAuthCallback = (type: string) => { return useMutation({ - mutationFn: async (code: string) => { - const res = await api(`/auth/oauth/${type}/callback?code=${code}`); + mutationFn: async (params: { code: string; verifier?: string }) => { + const res = await api(`/auth/oauth/${type}/callback`, { params }); const { data } = loginResultSchema.safeParse(res); if (!data) { throw new Error("Invalid response!"); diff --git a/frontend/pages/auth/login.tsx b/frontend/pages/auth/login.tsx index 9597a96..a5abdfb 100644 --- a/frontend/pages/auth/login.tsx +++ b/frontend/pages/auth/login.tsx @@ -14,6 +14,7 @@ import tamaguiConfig from "@/tamagui.config"; import { useLoginMutation } from "./hooks"; import LoginGithubButton from "./components/login-github"; import { useServerConfig } from "@/hooks/useServerConfig"; +import LoginGitlabButton from "./components/login-gitlab"; WebBrowser.maybeCompleteAuthSession(); @@ -109,6 +110,7 @@ export default function LoginPage() { {oauthList.includes("github") && } + {oauthList.includes("gitlab") && } )} diff --git a/server/app/auth/oauth_github.go b/server/app/auth/oauth_github.go index 21c9ec3..d476529 100644 --- a/server/app/auth/oauth_github.go +++ b/server/app/auth/oauth_github.go @@ -16,21 +16,22 @@ import ( "rul.sh/vaulterm/server/utils" ) -var config *oauth2.Config +var githubCfg *oauth2.Config func getGithubConfig() *oauth2.Config { - if config != nil { - return config + if githubCfg != nil { + return githubCfg } - config = &oauth2.Config{ + githubCfg = &oauth2.Config{ ClientID: os.Getenv("GITHUB_CLIENT_ID"), ClientSecret: os.Getenv("GITHUB_CLIENT_SECRET"), Endpoint: github.Endpoint, - RedirectURL: "http://localhost:3000/auth/oauth/github/callback", - Scopes: []string{"read:user"}, + // RedirectURL: "http://localhost:3000/auth/oauth/github/callback", + RedirectURL: "http://localhost:8081", + Scopes: []string{"read:user"}, } - return config + return githubCfg } func githubRedir(c *fiber.Ctx) error { diff --git a/server/app/auth/oauth_gitlab.go b/server/app/auth/oauth_gitlab.go new file mode 100644 index 0000000..442ae27 --- /dev/null +++ b/server/app/auth/oauth_gitlab.go @@ -0,0 +1,147 @@ +package auth + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "log" + "os" + "strconv" + + "github.com/gofiber/fiber/v2" + "golang.org/x/oauth2" + "golang.org/x/oauth2/gitlab" + "gorm.io/gorm" + "rul.sh/vaulterm/server/models" + "rul.sh/vaulterm/server/utils" +) + +type GitlabCfg struct { + oauth2.Config + verifier string + challenge string +} + +var gitlabCfg *GitlabCfg + +func getGitlabConfig() *GitlabCfg { + if gitlabCfg != nil { + return gitlabCfg + } + + oauthCfg := oauth2.Config{ + ClientID: os.Getenv("GITLAB_CLIENT_ID"), + ClientSecret: os.Getenv("GITLAB_CLIENT_SECRET"), + Endpoint: gitlab.Endpoint, + // RedirectURL: "http://localhost:3000/auth/oauth/gitlab/callback", + RedirectURL: "http://localhost:8081", + Scopes: []string{"read_user"}, + } + verifier := oauth2.GenerateVerifier() + challenge := oauth2.S256ChallengeFromVerifier(verifier) + + gitlabCfg = &GitlabCfg{ + Config: oauthCfg, + verifier: verifier, + challenge: challenge, + } + return gitlabCfg +} + +func gitlabRedir(c *fiber.Ctx) error { + // Redirect to Gitlab login page + url := getGitlabConfig(). + AuthCodeURL("login", oauth2.S256ChallengeOption(getGitlabConfig().verifier)) + return c.Redirect(url) +} + +func gitlabCallback(c *fiber.Ctx) error { + cfg := getGitlabConfig() + code := c.Query("code") + verifier := c.Query("verifier") + + if code == "" { + return c.Status(fiber.StatusBadRequest).SendString("Missing code") + } + if verifier == "" { + verifier = cfg.verifier + } + + // Exchange code for a token + token, err := cfg.Exchange(c.Context(), code, oauth2.VerifierOption(verifier)) + if err != nil { + log.Println(token, err) + return c.Status(fiber.StatusInternalServerError).SendString("Failed to exchange token") + } + + // Retrieve user info + client := cfg.Client(c.Context(), token) + resp, err := client.Get("https://gitlab.com/api/v4/user") + if err != nil { + return c.Status(fiber.StatusInternalServerError).SendString("Failed to get user info") + } + defer resp.Body.Close() + + body, _ := io.ReadAll(resp.Body) + if resp.StatusCode != 200 { + return c.Status(fiber.StatusInternalServerError). + SendString(fmt.Sprintf("Gitlab API error: %s", string(body))) + } + + // Parse user info + var user struct { + Username string `json:"username"` + ID int `json:"id"` + Name string `json:"name"` + AvatarURL string `json:"avatar_url"` + Email string `json:"email"` + } + + if err := json.Unmarshal(body, &user); err != nil { + return c.Status(fiber.StatusInternalServerError).SendString("Failed to parse user info") + } + + repo := NewRepository() + accountId := strconv.Itoa(user.ID) + userAccount, err := repo.FindUserAccount("gitlab", accountId) + + // Register the user if the account not yet registered + if errors.Is(err, gorm.ErrRecordNotFound) { + acc := models.UserAccount{ + Type: "gitlab", + AccountID: accountId, + Username: user.Username, + Email: user.Email, + } + user := models.User{ + Name: user.Name, + Role: models.UserRoleUser, + Image: user.AvatarURL, + Accounts: []*models.UserAccount{&acc}, + } + + sessionId, err := repo.CreateUser(&user) + if err != nil { + return utils.ResponseError(c, err, 500) + } + + return c.JSON(fiber.Map{ + "user": user, + "sessionId": sessionId, + }) + } + + if err != nil { + return utils.ResponseError(c, err, 500) + } + sessionId, err := repo.CreateUserSession(&userAccount.User) + if err != nil { + return utils.ResponseError(c, err, 500) + } + + return c.JSON(fiber.Map{ + "user": userAccount.User, + "sessionId": sessionId, + }) +} diff --git a/server/app/auth/repository.go b/server/app/auth/repository.go index 834ceef..d1240e1 100644 --- a/server/app/auth/repository.go +++ b/server/app/auth/repository.go @@ -3,8 +3,8 @@ package auth import ( "gorm.io/gorm" "rul.sh/vaulterm/server/db" - "rul.sh/vaulterm/server/lib" "rul.sh/vaulterm/server/models" + "rul.sh/vaulterm/server/utils" ) type Auth struct{ db *gorm.DB } @@ -30,7 +30,7 @@ func (r *Auth) FindUserAccount(accountType string, accountId string) (*models.Us } func (r *Auth) CreateUserSession(user *models.User) (string, error) { - sessionId, err := lib.GenerateSessionID(20) + sessionId, err := utils.GenerateSessionID(20) if err != nil { return "", err } diff --git a/server/app/auth/router.go b/server/app/auth/router.go index de97111..a4dc1b2 100644 --- a/server/app/auth/router.go +++ b/server/app/auth/router.go @@ -19,6 +19,8 @@ func Router(app *fiber.App) { oauth := router.Group("/oauth") oauth.Get("/github", githubRedir) oauth.Get("/github/callback", githubCallback) + oauth.Get("/gitlab", gitlabRedir) + oauth.Get("/gitlab/callback", gitlabCallback) } func login(c *fiber.Ctx) error { @@ -40,7 +42,7 @@ func login(c *fiber.Ctx) error { } } - if valid := lib.VerifyPassword(body.Password, user.Password); !valid { + if valid := utils.VerifyPassword(body.Password, user.Password); !valid { return &fiber.Error{ Code: fiber.StatusUnauthorized, Message: "Username or password is invalid", @@ -59,7 +61,7 @@ func login(c *fiber.Ctx) error { } func getUser(c *fiber.Ctx) error { - user := utils.GetUser(c) + user := lib.GetUser(c) teams := []TeamWithRole{} for _, item := range user.Teams { @@ -96,15 +98,15 @@ func register(c *fiber.Ctx) error { } } - password, err := lib.HashPassword(body.Password) + password, err := utils.HashPassword(body.Password) if err != nil { return utils.ResponseError(c, err, 500) } user := &models.User{ Name: body.Name, - Username: body.Username, - Email: body.Email, + Username: &body.Username, + Email: &body.Email, Password: password, Role: models.UserRoleUser, } diff --git a/server/app/hosts/repository.go b/server/app/hosts/repository.go index 313fa52..676d936 100644 --- a/server/app/hosts/repository.go +++ b/server/app/hosts/repository.go @@ -3,13 +3,13 @@ package hosts import ( "gorm.io/gorm" "rul.sh/vaulterm/server/db" + "rul.sh/vaulterm/server/lib" "rul.sh/vaulterm/server/models" - "rul.sh/vaulterm/server/utils" ) type Hosts struct { db *gorm.DB - User *utils.UserContext + User *lib.UserContext } func NewRepository(r *Hosts) *Hosts { diff --git a/server/app/hosts/router.go b/server/app/hosts/router.go index 9601d18..cdefe61 100644 --- a/server/app/hosts/router.go +++ b/server/app/hosts/router.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/gofiber/fiber/v2" + "rul.sh/vaulterm/server/lib" "rul.sh/vaulterm/server/models" "rul.sh/vaulterm/server/utils" ) @@ -25,7 +26,7 @@ func getAll(c *fiber.Ctx) error { teamId := c.Query("teamId") parentId := c.Query("parentId") - user := utils.GetUser(c) + user := lib.GetUser(c) repo := NewRepository(&Hosts{User: user}) if teamId != "" && !user.IsInTeam(&teamId) { @@ -48,7 +49,7 @@ func create(c *fiber.Ctx) error { return utils.ResponseError(c, err, 500) } - user := utils.GetUser(c) + user := lib.GetUser(c) repo := NewRepository(&Hosts{User: user}) if body.TeamID != nil && !user.TeamCanWrite(body.TeamID) { @@ -87,7 +88,7 @@ func update(c *fiber.Ctx) error { return utils.ResponseError(c, err, 500) } - user := utils.GetUser(c) + user := lib.GetUser(c) repo := NewRepository(&Hosts{User: user}) id := c.Params("id") @@ -126,7 +127,7 @@ func update(c *fiber.Ctx) error { } func delete(c *fiber.Ctx) error { - user := utils.GetUser(c) + user := lib.GetUser(c) repo := NewRepository(&Hosts{User: user}) id := c.Params("id") @@ -149,7 +150,7 @@ func delete(c *fiber.Ctx) error { } func move(c *fiber.Ctx) error { - user := utils.GetUser(c) + user := lib.GetUser(c) repo := NewRepository(&Hosts{User: user}) // validate request diff --git a/server/app/hosts/utils.go b/server/app/hosts/utils.go index cf12fdd..9303aa3 100644 --- a/server/app/hosts/utils.go +++ b/server/app/hosts/utils.go @@ -7,11 +7,10 @@ import ( "rul.sh/vaulterm/server/app/keychains" "rul.sh/vaulterm/server/lib" "rul.sh/vaulterm/server/models" - "rul.sh/vaulterm/server/utils" ) func tryConnect(c *fiber.Ctx, host *models.Host) (string, error) { - user := utils.GetUser(c) + user := lib.GetUser(c) keyRepo := keychains.NewRepository(&keychains.Keychains{User: user}) var key map[string]interface{} diff --git a/server/app/keychains/repository.go b/server/app/keychains/repository.go index 23cc079..614165a 100644 --- a/server/app/keychains/repository.go +++ b/server/app/keychains/repository.go @@ -3,13 +3,13 @@ package keychains import ( "gorm.io/gorm" "rul.sh/vaulterm/server/db" + "rul.sh/vaulterm/server/lib" "rul.sh/vaulterm/server/models" - "rul.sh/vaulterm/server/utils" ) type Keychains struct { db *gorm.DB - User *utils.UserContext + User *lib.UserContext } func NewRepository(r *Keychains) *Keychains { diff --git a/server/app/keychains/router.go b/server/app/keychains/router.go index 95ccbfc..a05184d 100644 --- a/server/app/keychains/router.go +++ b/server/app/keychains/router.go @@ -5,6 +5,7 @@ import ( "net/http" "github.com/gofiber/fiber/v2" + "rul.sh/vaulterm/server/lib" "rul.sh/vaulterm/server/models" "rul.sh/vaulterm/server/utils" ) @@ -26,7 +27,7 @@ func getAll(c *fiber.Ctx) error { teamId := c.Query("teamId") withData := c.Query("withData") - user := utils.GetUser(c) + user := lib.GetUser(c) repo := NewRepository(&Keychains{User: user}) if teamId != "" && !user.IsInTeam(&teamId) { @@ -69,7 +70,7 @@ func create(c *fiber.Ctx) error { return utils.ResponseError(c, err, 500) } - user := utils.GetUser(c) + user := lib.GetUser(c) repo := NewRepository(&Keychains{User: user}) if body.TeamID != nil && !user.TeamCanWrite(body.TeamID) { @@ -100,7 +101,7 @@ func update(c *fiber.Ctx) error { return utils.ResponseError(c, err, 500) } - user := utils.GetUser(c) + user := lib.GetUser(c) repo := NewRepository(&Keychains{User: user}) id := c.Params("id") diff --git a/server/app/server/router.go b/server/app/server/router.go index 1064b6a..7efa605 100644 --- a/server/app/server/router.go +++ b/server/app/server/router.go @@ -22,8 +22,9 @@ func getServerInfo(c *fiber.Ctx) error { func getConfig(c *fiber.Ctx) error { config := fiber.Map{ - "oauth": "github", + "oauth": os.Getenv("OAUTH_ENABLED"), "github_client_id": os.Getenv("GITHUB_CLIENT_ID"), + "gitlab_client_id": os.Getenv("GITLAB_CLIENT_ID"), } return c.JSON(config) } diff --git a/server/app/teams/members/repository.go b/server/app/teams/members/repository.go index ffc319b..3bbbf65 100644 --- a/server/app/teams/members/repository.go +++ b/server/app/teams/members/repository.go @@ -4,13 +4,13 @@ import ( "gorm.io/gorm" "gorm.io/gorm/clause" "rul.sh/vaulterm/server/db" + "rul.sh/vaulterm/server/lib" "rul.sh/vaulterm/server/models" - "rul.sh/vaulterm/server/utils" ) type TeamMembers struct { db *gorm.DB - User *utils.UserContext + User *lib.UserContext } func NewRepository(r *TeamMembers) *TeamMembers { diff --git a/server/app/teams/members/router.go b/server/app/teams/members/router.go index 95732f1..df41bfd 100644 --- a/server/app/teams/members/router.go +++ b/server/app/teams/members/router.go @@ -6,6 +6,7 @@ import ( "github.com/gofiber/fiber/v2" "rul.sh/vaulterm/server/app/teams" "rul.sh/vaulterm/server/app/users" + "rul.sh/vaulterm/server/lib" "rul.sh/vaulterm/server/models" "rul.sh/vaulterm/server/utils" ) @@ -20,7 +21,7 @@ func Router(app fiber.Router) { } // func getAll(c *fiber.Ctx) error { -// user := utils.GetUser(c) +// user := lib.GetUser(c) // repo := NewRepository(&TeamMembers{User: user}) // rows, err := repo.GetAll() @@ -37,7 +38,7 @@ func invite(c *fiber.Ctx) error { return utils.ResponseError(c, err, 500) } - user := utils.GetUser(c) + user := lib.GetUser(c) teamRepo := teams.NewRepository(&teams.Teams{User: user}) repo := NewRepository(&TeamMembers{User: user}) @@ -70,7 +71,7 @@ func setRole(c *fiber.Ctx) error { return utils.ResponseError(c, err, 500) } - user := utils.GetUser(c) + user := lib.GetUser(c) teamRepo := teams.NewRepository(&teams.Teams{User: user}) repo := NewRepository(&TeamMembers{User: user}) @@ -103,7 +104,7 @@ func setRole(c *fiber.Ctx) error { } func remove(c *fiber.Ctx) error { - user := utils.GetUser(c) + user := lib.GetUser(c) teamRepo := teams.NewRepository(&teams.Teams{User: user}) repo := NewRepository(&TeamMembers{User: user}) diff --git a/server/app/teams/repository.go b/server/app/teams/repository.go index b3e06e6..14b859b 100644 --- a/server/app/teams/repository.go +++ b/server/app/teams/repository.go @@ -3,13 +3,13 @@ package teams import ( "gorm.io/gorm" "rul.sh/vaulterm/server/db" + "rul.sh/vaulterm/server/lib" "rul.sh/vaulterm/server/models" - "rul.sh/vaulterm/server/utils" ) type Teams struct { db *gorm.DB - User *utils.UserContext + User *lib.UserContext } func NewRepository(r *Teams) *Teams { diff --git a/server/app/teams/router.go b/server/app/teams/router.go index 82491b8..3e52993 100644 --- a/server/app/teams/router.go +++ b/server/app/teams/router.go @@ -5,6 +5,7 @@ import ( "net/http" "github.com/gofiber/fiber/v2" + "rul.sh/vaulterm/server/lib" "rul.sh/vaulterm/server/models" "rul.sh/vaulterm/server/utils" ) @@ -22,7 +23,7 @@ func Router(app fiber.Router) fiber.Router { } func getAll(c *fiber.Ctx) error { - user := utils.GetUser(c) + user := lib.GetUser(c) repo := NewRepository(&Teams{User: user}) rows, err := repo.GetAll() @@ -34,7 +35,7 @@ func getAll(c *fiber.Ctx) error { } func getById(c *fiber.Ctx) error { - user := utils.GetUser(c) + user := lib.GetUser(c) repo := NewRepository(&Teams{User: user}) id := c.Params("id") @@ -52,7 +53,7 @@ func create(c *fiber.Ctx) error { return utils.ResponseError(c, err, 500) } - user := utils.GetUser(c) + user := lib.GetUser(c) repo := NewRepository(&Teams{User: user}) item := &models.Team{ @@ -73,7 +74,7 @@ func update(c *fiber.Ctx) error { return utils.ResponseError(c, err, 500) } - user := utils.GetUser(c) + user := lib.GetUser(c) repo := NewRepository(&Teams{User: user}) id := c.Params("id") @@ -98,7 +99,7 @@ func update(c *fiber.Ctx) error { } func delete(c *fiber.Ctx) error { - user := utils.GetUser(c) + user := lib.GetUser(c) repo := NewRepository(&Teams{User: user}) id := c.Params("id") diff --git a/server/app/users/repository.go b/server/app/users/repository.go index 7ef95aa..c8cc60c 100644 --- a/server/app/users/repository.go +++ b/server/app/users/repository.go @@ -3,13 +3,13 @@ package users import ( "gorm.io/gorm" "rul.sh/vaulterm/server/db" + "rul.sh/vaulterm/server/lib" "rul.sh/vaulterm/server/models" - "rul.sh/vaulterm/server/utils" ) type Users struct { db *gorm.DB - User *utils.UserContext + User *lib.UserContext } func NewRepository(r *Users) *Users { diff --git a/server/app/ws/stats/stats.go b/server/app/ws/stats/stats.go index e1b24ae..f129e2e 100644 --- a/server/app/ws/stats/stats.go +++ b/server/app/ws/stats/stats.go @@ -5,13 +5,12 @@ import ( "rul.sh/vaulterm/server/app/hosts" "rul.sh/vaulterm/server/lib" "rul.sh/vaulterm/server/models" - "rul.sh/vaulterm/server/utils" ) func HandleStats(c *websocket.Conn) { hostId := c.Query("hostId") - user := utils.GetUserWs(c) + user := lib.GetUserWs(c) hostRepo := hosts.NewRepository(&hosts.Hosts{User: user}) data, _ := hostRepo.GetWithKeys(hostId) diff --git a/server/app/ws/term/term.go b/server/app/ws/term/term.go index b1d9b71..87171b7 100644 --- a/server/app/ws/term/term.go +++ b/server/app/ws/term/term.go @@ -15,7 +15,7 @@ import ( func HandleTerm(c *websocket.Conn) { hostId := c.Query("hostId") - user := utils.GetUserWs(c) + user := lib.GetUserWs(c) hostRepo := hosts.NewRepository(&hosts.Hosts{User: user}) data, err := hostRepo.GetWithKeys(hostId) diff --git a/server/db/seeders.go b/server/db/seeders.go index 3daa9d5..e8f4434 100644 --- a/server/db/seeders.go +++ b/server/db/seeders.go @@ -2,8 +2,8 @@ package db import ( "gorm.io/gorm" - "rul.sh/vaulterm/server/lib" "rul.sh/vaulterm/server/models" + "rul.sh/vaulterm/server/utils" ) type SeedFn func(*gorm.DB) error @@ -23,7 +23,7 @@ func seedUsers(tx *gorm.DB) error { return nil } - testPasswd, err := lib.HashPassword("123456") + testPasswd, err := utils.HashPassword("123456") if err != nil { return err } @@ -42,38 +42,38 @@ func seedUsers(tx *gorm.DB) error { userList := []*models.User{ { Name: "Admin", - Username: "admin", + Username: utils.StringPtr("admin"), Password: testPasswd, - Email: "admin@mail.com", + Email: utils.StringPtr("admin@mail.com"), Role: models.UserRoleAdmin, }, - { - Name: "John Doe", - Username: "user", - Password: testPasswd, - Email: "user@mail.com", - }, - { - Name: "Mary Doe", - Username: "user2", - Password: testPasswd, - Email: "user2@mail.com", - }, + // { + // Name: "John Doe", + // Username: "user", + // Password: testPasswd, + // Email: "user@mail.com", + // }, + // { + // Name: "Mary Doe", + // Username: "user2", + // Password: testPasswd, + // Email: "user2@mail.com", + // }, } if res := tx.Create(&userList); res.Error != nil { return res.Error } - teamMembers := []models.TeamMembers{ - {TeamID: teams[0].ID, UserID: userList[0].ID, Role: models.TeamRoleOwner}, - {TeamID: teams[0].ID, UserID: userList[1].ID, Role: models.TeamRoleAdmin}, - {TeamID: teams[0].ID, UserID: userList[2].ID, Role: models.TeamRoleMember}, - } + // teamMembers := []models.TeamMembers{ + // {TeamID: teams[0].ID, UserID: userList[0].ID, Role: models.TeamRoleOwner}, + // {TeamID: teams[0].ID, UserID: userList[1].ID, Role: models.TeamRoleAdmin}, + // {TeamID: teams[0].ID, UserID: userList[2].ID, Role: models.TeamRoleMember}, + // } - if res := tx.Create(&teamMembers); res.Error != nil { - return res.Error - } + // if res := tx.Create(&teamMembers); res.Error != nil { + // return res.Error + // } return nil } diff --git a/server/utils/context.go b/server/lib/context.go similarity index 96% rename from server/utils/context.go rename to server/lib/context.go index 18bbc77..1ac6ff2 100644 --- a/server/utils/context.go +++ b/server/lib/context.go @@ -1,4 +1,4 @@ -package utils +package lib import ( "github.com/gofiber/contrib/websocket" diff --git a/server/lib/incus.go b/server/lib/incus.go index 958edfb..fb658d5 100644 --- a/server/lib/incus.go +++ b/server/lib/incus.go @@ -8,6 +8,8 @@ import ( "io" "log" "net/http" + + "rul.sh/vaulterm/server/utils" ) type IncusServer struct { @@ -22,7 +24,7 @@ type IncusFetchConfig struct { } func (i *IncusServer) GetCertificate() (*tls.Certificate, error) { - return LoadClientCertificate(i.ClientCert, i.ClientKey) + return utils.LoadClientCertificate(i.ClientCert, i.ClientKey) } func (i *IncusServer) Fetch(method string, url string, cfg *IncusFetchConfig) ([]byte, error) { diff --git a/server/models/keychain.go b/server/models/keychain.go index 776037c..4a06c62 100644 --- a/server/models/keychain.go +++ b/server/models/keychain.go @@ -3,7 +3,7 @@ package models import ( "encoding/json" - "rul.sh/vaulterm/server/lib" + "rul.sh/vaulterm/server/utils" ) const ( @@ -36,7 +36,7 @@ func (k *Keychain) EncryptData(data interface{}) error { return err } - enc, err := lib.Encrypt(string(jsonData)) + enc, err := utils.Encrypt(string(jsonData)) if err == nil { k.Data = enc } @@ -45,7 +45,7 @@ func (k *Keychain) EncryptData(data interface{}) error { func (k *Keychain) DecryptData(data interface{}) error { // Decrypt stored data - dec, err := lib.Decrypt(k.Data) + dec, err := utils.Decrypt(k.Data) if err != nil { return err } diff --git a/server/models/user.go b/server/models/user.go index 7dc9417..3d3236b 100644 --- a/server/models/user.go +++ b/server/models/user.go @@ -12,12 +12,12 @@ const ( type User struct { Model - Name string `json:"name"` - Username string `json:"username" gorm:"unique"` - Password string `json:"-"` - Email string `json:"email" gorm:"unique"` - Role string `json:"role" gorm:"default:user;not null;index:users_role_idx;type:varchar(8)"` - Image string `json:"image" gorm:"type:varchar(255)"` + Name string `json:"name"` + Username *string `json:"username" gorm:"unique"` + Password string `json:"-"` + Email *string `json:"email" gorm:"unique"` + Role string `json:"role" gorm:"default:user;not null;index:users_role_idx;type:varchar(8)"` + Image string `json:"image" gorm:"type:varchar(255)"` Teams []*TeamMembers `json:"teams" gorm:"foreignKey:UserID"` Accounts []*UserAccount `json:"accounts" gorm:"foreignKey:UserID"` diff --git a/server/utils/config.go b/server/utils/config.go index 7066dc1..d6ab984 100644 --- a/server/utils/config.go +++ b/server/utils/config.go @@ -4,8 +4,6 @@ import ( "fmt" "os" "path/filepath" - - "rul.sh/vaulterm/server/lib" ) func GetDataPath(resolveFile string) string { @@ -35,7 +33,7 @@ func CheckAndCreateEnvFile() error { } // File doesn't exist, so create it - randomKey, err := lib.GenerateRandomKey() + randomKey, err := GenerateRandomKey() if err != nil { return err } diff --git a/server/lib/crypto.go b/server/utils/crypto.go similarity index 99% rename from server/lib/crypto.go rename to server/utils/crypto.go index 39d4920..ac36b8c 100644 --- a/server/lib/crypto.go +++ b/server/utils/crypto.go @@ -1,4 +1,4 @@ -package lib +package utils import ( "crypto/aes" diff --git a/server/utils/string.go b/server/utils/string.go new file mode 100644 index 0000000..088ee06 --- /dev/null +++ b/server/utils/string.go @@ -0,0 +1,5 @@ +package utils + +func StringPtr(s string) *string { + return &s +}