mirror of
https://github.com/thomiceli/opengist.git
synced 2024-12-22 20:42:40 +00:00
feat: default visibility (#155)
Signed-off-by: jolheiser <john.olheiser@gmail.com>
This commit is contained in:
parent
943212e492
commit
246f12c8cb
9 changed files with 187 additions and 145 deletions
|
@ -1,14 +1,48 @@
|
||||||
package db
|
package db
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/labstack/echo/v4"
|
"fmt"
|
||||||
"github.com/thomiceli/opengist/internal/git"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/thomiceli/opengist/internal/git"
|
||||||
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Visibility int
|
||||||
|
|
||||||
|
const (
|
||||||
|
PublicVisibility Visibility = iota
|
||||||
|
UnlistedVisibility
|
||||||
|
PrivateVisibility
|
||||||
|
)
|
||||||
|
|
||||||
|
func (v Visibility) Next() Visibility {
|
||||||
|
switch v {
|
||||||
|
case PublicVisibility:
|
||||||
|
return UnlistedVisibility
|
||||||
|
case UnlistedVisibility:
|
||||||
|
return PrivateVisibility
|
||||||
|
default:
|
||||||
|
return PublicVisibility
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ParseVisibility[T string | int](v T) (Visibility, error) {
|
||||||
|
switch s := fmt.Sprint(v); s {
|
||||||
|
case "0":
|
||||||
|
return PublicVisibility, nil
|
||||||
|
case "1":
|
||||||
|
return UnlistedVisibility, nil
|
||||||
|
case "2":
|
||||||
|
return PrivateVisibility, nil
|
||||||
|
default:
|
||||||
|
return -1, fmt.Errorf("unknown visibility %q", s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type Gist struct {
|
type Gist struct {
|
||||||
ID uint `gorm:"primaryKey"`
|
ID uint `gorm:"primaryKey"`
|
||||||
Uuid string
|
Uuid string
|
||||||
|
@ -16,7 +50,7 @@ type Gist struct {
|
||||||
Preview string
|
Preview string
|
||||||
PreviewFilename string
|
PreviewFilename string
|
||||||
Description string
|
Description string
|
||||||
Private int // 0: public, 1: unlisted, 2: private
|
Private Visibility // 0: public, 1: unlisted, 2: private
|
||||||
UserID uint
|
UserID uint
|
||||||
User User
|
User User
|
||||||
NbFiles int
|
NbFiles int
|
||||||
|
@ -386,12 +420,12 @@ func (gist *Gist) UpdatePreviewAndCount() error {
|
||||||
// -- DTO -- //
|
// -- DTO -- //
|
||||||
|
|
||||||
type GistDTO struct {
|
type GistDTO struct {
|
||||||
Title string `validate:"max=250" form:"title"`
|
Title string `validate:"max=250" form:"title"`
|
||||||
Description string `validate:"max=1000" form:"description"`
|
Description string `validate:"max=1000" form:"description"`
|
||||||
Private int `validate:"number,min=0,max=2" form:"private"`
|
Private Visibility `validate:"number,min=0,max=2" form:"private"`
|
||||||
Files []FileDTO `validate:"min=1,dive"`
|
Files []FileDTO `validate:"min=1,dive"`
|
||||||
Name []string `form:"name"`
|
Name []string `form:"name"`
|
||||||
Content []string `form:"content"`
|
Content []string `form:"content"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type FileDTO struct {
|
type FileDTO struct {
|
||||||
|
|
|
@ -100,7 +100,6 @@ func GetUsersFromEmails(emailsSet map[string]struct{}) (map[string]*User, error)
|
||||||
err := db.
|
err := db.
|
||||||
Where("email IN ?", emails).
|
Where("email IN ?", emails).
|
||||||
Find(&users).Error
|
Find(&users).Error
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,16 +4,17 @@ import (
|
||||||
"archive/zip"
|
"archive/zip"
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/labstack/echo/v4"
|
|
||||||
"github.com/thomiceli/opengist/internal/config"
|
|
||||||
"github.com/thomiceli/opengist/internal/db"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
"html/template"
|
"html/template"
|
||||||
"net/url"
|
"net/url"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/thomiceli/opengist/internal/config"
|
||||||
|
"github.com/thomiceli/opengist/internal/db"
|
||||||
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
func gistInit(next echo.HandlerFunc) echo.HandlerFunc {
|
func gistInit(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
|
@ -30,7 +31,7 @@ func gistInit(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return notFound("Gist not found")
|
return notFound("Gist not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
if gist.Private == 2 {
|
if gist.Private == db.PrivateVisibility {
|
||||||
if currUser == nil || currUser.ID != gist.UserID {
|
if currUser == nil || currUser.ID != gist.UserID {
|
||||||
return notFound("Gist not found")
|
return notFound("Gist not found")
|
||||||
}
|
}
|
||||||
|
@ -433,7 +434,7 @@ func processCreate(ctx echo.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func toggleVisibility(ctx echo.Context) error {
|
func toggleVisibility(ctx echo.Context) error {
|
||||||
var gist = getData(ctx, "gist").(*db.Gist)
|
gist := getData(ctx, "gist").(*db.Gist)
|
||||||
|
|
||||||
gist.Private = (gist.Private + 1) % 3
|
gist.Private = (gist.Private + 1) % 3
|
||||||
if err := gist.Update(); err != nil {
|
if err := gist.Update(); err != nil {
|
||||||
|
@ -445,7 +446,7 @@ func toggleVisibility(ctx echo.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteGist(ctx echo.Context) error {
|
func deleteGist(ctx echo.Context) error {
|
||||||
var gist = getData(ctx, "gist").(*db.Gist)
|
gist := getData(ctx, "gist").(*db.Gist)
|
||||||
|
|
||||||
if err := gist.Delete(); err != nil {
|
if err := gist.Delete(); err != nil {
|
||||||
return errorRes(500, "Error deleting this gist", err)
|
return errorRes(500, "Error deleting this gist", err)
|
||||||
|
@ -456,7 +457,7 @@ func deleteGist(ctx echo.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func like(ctx echo.Context) error {
|
func like(ctx echo.Context) error {
|
||||||
var gist = getData(ctx, "gist").(*db.Gist)
|
gist := getData(ctx, "gist").(*db.Gist)
|
||||||
currentUser := getUserLogged(ctx)
|
currentUser := getUserLogged(ctx)
|
||||||
|
|
||||||
hasLiked, err := currentUser.HasLiked(gist)
|
hasLiked, err := currentUser.HasLiked(gist)
|
||||||
|
@ -482,7 +483,7 @@ func like(ctx echo.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func fork(ctx echo.Context) error {
|
func fork(ctx echo.Context) error {
|
||||||
var gist = getData(ctx, "gist").(*db.Gist)
|
gist := getData(ctx, "gist").(*db.Gist)
|
||||||
currentUser := getUserLogged(ctx)
|
currentUser := getUserLogged(ctx)
|
||||||
|
|
||||||
alreadyForked, err := gist.GetForkParent(currentUser)
|
alreadyForked, err := gist.GetForkParent(currentUser)
|
||||||
|
@ -535,7 +536,6 @@ func fork(ctx echo.Context) error {
|
||||||
func rawFile(ctx echo.Context) error {
|
func rawFile(ctx echo.Context) error {
|
||||||
gist := getData(ctx, "gist").(*db.Gist)
|
gist := getData(ctx, "gist").(*db.Gist)
|
||||||
file, err := gist.File(ctx.Param("revision"), ctx.Param("file"), false)
|
file, err := gist.File(ctx.Param("revision"), ctx.Param("file"), false)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errorRes(500, "Error getting file content", err)
|
return errorRes(500, "Error getting file content", err)
|
||||||
}
|
}
|
||||||
|
@ -550,7 +550,6 @@ func rawFile(ctx echo.Context) error {
|
||||||
func downloadFile(ctx echo.Context) error {
|
func downloadFile(ctx echo.Context) error {
|
||||||
gist := getData(ctx, "gist").(*db.Gist)
|
gist := getData(ctx, "gist").(*db.Gist)
|
||||||
file, err := gist.File(ctx.Param("revision"), ctx.Param("file"), false)
|
file, err := gist.File(ctx.Param("revision"), ctx.Param("file"), false)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errorRes(500, "Error getting file content", err)
|
return errorRes(500, "Error getting file content", err)
|
||||||
}
|
}
|
||||||
|
@ -572,7 +571,7 @@ func downloadFile(ctx echo.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func edit(ctx echo.Context) error {
|
func edit(ctx echo.Context) error {
|
||||||
var gist = getData(ctx, "gist").(*db.Gist)
|
gist := getData(ctx, "gist").(*db.Gist)
|
||||||
|
|
||||||
files, err := gist.Files("HEAD")
|
files, err := gist.Files("HEAD")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -586,8 +585,8 @@ func edit(ctx echo.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func downloadZip(ctx echo.Context) error {
|
func downloadZip(ctx echo.Context) error {
|
||||||
var gist = getData(ctx, "gist").(*db.Gist)
|
gist := getData(ctx, "gist").(*db.Gist)
|
||||||
var revision = ctx.Param("revision")
|
revision := ctx.Param("revision")
|
||||||
|
|
||||||
files, err := gist.Files(revision)
|
files, err := gist.Files(revision)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -631,7 +630,7 @@ func downloadZip(ctx echo.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func likes(ctx echo.Context) error {
|
func likes(ctx echo.Context) error {
|
||||||
var gist = getData(ctx, "gist").(*db.Gist)
|
gist := getData(ctx, "gist").(*db.Gist)
|
||||||
|
|
||||||
pageInt := getPage(ctx)
|
pageInt := getPage(ctx)
|
||||||
|
|
||||||
|
@ -650,7 +649,7 @@ func likes(ctx echo.Context) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func forks(ctx echo.Context) error {
|
func forks(ctx echo.Context) error {
|
||||||
var gist = getData(ctx, "gist").(*db.Gist)
|
gist := getData(ctx, "gist").(*db.Gist)
|
||||||
pageInt := getPage(ctx)
|
pageInt := getPage(ctx)
|
||||||
|
|
||||||
currentUser := getUserLogged(ctx)
|
currentUser := getUserLogged(ctx)
|
||||||
|
|
|
@ -6,13 +6,6 @@ import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/labstack/echo/v4"
|
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
"github.com/thomiceli/opengist/internal/db"
|
|
||||||
"github.com/thomiceli/opengist/internal/git"
|
|
||||||
"github.com/thomiceli/opengist/internal/memdb"
|
|
||||||
"gorm.io/gorm"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
@ -21,6 +14,14 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
"github.com/thomiceli/opengist/internal/db"
|
||||||
|
"github.com/thomiceli/opengist/internal/git"
|
||||||
|
"github.com/thomiceli/opengist/internal/memdb"
|
||||||
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
var routes = []struct {
|
var routes = []struct {
|
||||||
|
@ -73,7 +74,7 @@ func gitHttp(ctx echo.Context) error {
|
||||||
// - user wants to clone/pull a private gist
|
// - user wants to clone/pull a private gist
|
||||||
// - gist is not found (obfuscation)
|
// - gist is not found (obfuscation)
|
||||||
// - admin setting to require login is set to true
|
// - admin setting to require login is set to true
|
||||||
if isPull && gist.Private != 2 && gist.ID != 0 && !getData(ctx, "RequireLogin").(bool) {
|
if isPull && gist.Private != db.PrivateVisibility && gist.ID != 0 && !getData(ctx, "RequireLogin").(bool) {
|
||||||
return route.handler(ctx)
|
return route.handler(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,16 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
htmlpkg "html"
|
||||||
|
"html/template"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gorilla/sessions"
|
"github.com/gorilla/sessions"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
"github.com/labstack/echo/v4/middleware"
|
"github.com/labstack/echo/v4/middleware"
|
||||||
|
@ -16,106 +26,99 @@ import (
|
||||||
"github.com/thomiceli/opengist/public"
|
"github.com/thomiceli/opengist/public"
|
||||||
"github.com/thomiceli/opengist/templates"
|
"github.com/thomiceli/opengist/templates"
|
||||||
"golang.org/x/text/language"
|
"golang.org/x/text/language"
|
||||||
htmlpkg "html"
|
|
||||||
"html/template"
|
|
||||||
"io"
|
|
||||||
"net/http"
|
|
||||||
"path/filepath"
|
|
||||||
"regexp"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var dev bool
|
var (
|
||||||
var store *sessions.CookieStore
|
dev bool
|
||||||
var re = regexp.MustCompile("[^a-z0-9]+")
|
store *sessions.CookieStore
|
||||||
var fm = template.FuncMap{
|
re = regexp.MustCompile("[^a-z0-9]+")
|
||||||
"split": strings.Split,
|
fm = template.FuncMap{
|
||||||
"indexByte": strings.IndexByte,
|
"split": strings.Split,
|
||||||
"toInt": func(i string) int {
|
"indexByte": strings.IndexByte,
|
||||||
val, _ := strconv.Atoi(i)
|
"toInt": func(i string) int {
|
||||||
return val
|
val, _ := strconv.Atoi(i)
|
||||||
},
|
return val
|
||||||
"inc": func(i int) int {
|
},
|
||||||
return i + 1
|
"inc": func(i int) int {
|
||||||
},
|
return i + 1
|
||||||
"splitGit": func(i string) []string {
|
},
|
||||||
return strings.FieldsFunc(i, func(r rune) bool {
|
"splitGit": func(i string) []string {
|
||||||
return r == ',' || r == ' '
|
return strings.FieldsFunc(i, func(r rune) bool {
|
||||||
})
|
return r == ',' || r == ' '
|
||||||
},
|
})
|
||||||
"lines": func(i string) []string {
|
},
|
||||||
return strings.Split(i, "\n")
|
"lines": func(i string) []string {
|
||||||
},
|
return strings.Split(i, "\n")
|
||||||
"isMarkdown": func(i string) bool {
|
},
|
||||||
return strings.ToLower(filepath.Ext(i)) == ".md"
|
"isMarkdown": func(i string) bool {
|
||||||
},
|
return strings.ToLower(filepath.Ext(i)) == ".md"
|
||||||
"isCsv": func(i string) bool {
|
},
|
||||||
return strings.ToLower(filepath.Ext(i)) == ".csv"
|
"isCsv": func(i string) bool {
|
||||||
},
|
return strings.ToLower(filepath.Ext(i)) == ".csv"
|
||||||
"csvFile": func(file *git.File) *git.CsvFile {
|
},
|
||||||
if strings.ToLower(filepath.Ext(file.Filename)) != ".csv" {
|
"csvFile": func(file *git.File) *git.CsvFile {
|
||||||
return nil
|
if strings.ToLower(filepath.Ext(file.Filename)) != ".csv" {
|
||||||
}
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
csvFile, err := git.ParseCsv(file)
|
csvFile, err := git.ParseCsv(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return csvFile
|
return csvFile
|
||||||
},
|
},
|
||||||
"httpStatusText": http.StatusText,
|
"httpStatusText": http.StatusText,
|
||||||
"loadedTime": func(startTime time.Time) string {
|
"loadedTime": func(startTime time.Time) string {
|
||||||
return fmt.Sprint(time.Since(startTime).Nanoseconds()/1e6) + "ms"
|
return fmt.Sprint(time.Since(startTime).Nanoseconds()/1e6) + "ms"
|
||||||
},
|
},
|
||||||
"slug": func(s string) string {
|
"slug": func(s string) string {
|
||||||
return strings.Trim(re.ReplaceAllString(strings.ToLower(s), "-"), "-")
|
return strings.Trim(re.ReplaceAllString(strings.ToLower(s), "-"), "-")
|
||||||
},
|
},
|
||||||
"avatarUrl": func(user *db.User, noGravatar bool) string {
|
"avatarUrl": func(user *db.User, noGravatar bool) string {
|
||||||
if user.AvatarURL != "" {
|
if user.AvatarURL != "" {
|
||||||
return user.AvatarURL
|
return user.AvatarURL
|
||||||
}
|
}
|
||||||
|
|
||||||
if user.MD5Hash != "" && !noGravatar {
|
if user.MD5Hash != "" && !noGravatar {
|
||||||
return "https://www.gravatar.com/avatar/" + user.MD5Hash + "?d=identicon&s=200"
|
return "https://www.gravatar.com/avatar/" + user.MD5Hash + "?d=identicon&s=200"
|
||||||
}
|
}
|
||||||
|
|
||||||
return defaultAvatar()
|
return defaultAvatar()
|
||||||
},
|
},
|
||||||
"asset": func(file string) string {
|
"asset": func(file string) string {
|
||||||
if dev {
|
if dev {
|
||||||
return "http://localhost:16157/" + file
|
return "http://localhost:16157/" + file
|
||||||
}
|
}
|
||||||
return config.C.ExternalUrl + "/" + manifestEntries[file].File
|
return config.C.ExternalUrl + "/" + manifestEntries[file].File
|
||||||
},
|
},
|
||||||
"dev": func() bool {
|
"dev": func() bool {
|
||||||
return dev
|
return dev
|
||||||
},
|
},
|
||||||
"defaultAvatar": defaultAvatar,
|
"defaultAvatar": defaultAvatar,
|
||||||
"visibilityStr": func(visibility int, lowercase bool) string {
|
"visibilityStr": func(visibility db.Visibility, lowercase bool) string {
|
||||||
s := "Public"
|
s := "Public"
|
||||||
switch visibility {
|
switch visibility {
|
||||||
case 1:
|
case 1:
|
||||||
s = "Unlisted"
|
s = "Unlisted"
|
||||||
case 2:
|
case 2:
|
||||||
s = "Private"
|
s = "Private"
|
||||||
}
|
}
|
||||||
|
|
||||||
if lowercase {
|
if lowercase {
|
||||||
return strings.ToLower(s)
|
return strings.ToLower(s)
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
},
|
},
|
||||||
"unescape": htmlpkg.UnescapeString,
|
"unescape": htmlpkg.UnescapeString,
|
||||||
"join": func(s ...string) string {
|
"join": func(s ...string) string {
|
||||||
return strings.Join(s, "")
|
return strings.Join(s, "")
|
||||||
},
|
},
|
||||||
"toStr": func(i interface{}) string {
|
"toStr": func(i interface{}) string {
|
||||||
return fmt.Sprint(i)
|
return fmt.Sprint(i)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
type Template struct {
|
type Template struct {
|
||||||
templates *template.Template
|
templates *template.Template
|
||||||
|
@ -159,7 +162,7 @@ func NewServer(isDev bool) *Server {
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
//e.Use(middleware.Recover())
|
// e.Use(middleware.Recover())
|
||||||
e.Use(middleware.Secure())
|
e.Use(middleware.Secure())
|
||||||
|
|
||||||
e.Renderer = &Template{
|
e.Renderer = &Template{
|
||||||
|
@ -316,7 +319,6 @@ func dataInit(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
|
|
||||||
func locale(next echo.HandlerFunc) echo.HandlerFunc {
|
func locale(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
return func(ctx echo.Context) error {
|
return func(ctx echo.Context) error {
|
||||||
|
|
||||||
// Check URL arguments
|
// Check URL arguments
|
||||||
lang := ctx.Request().URL.Query().Get("lang")
|
lang := ctx.Request().URL.Query().Get("lang")
|
||||||
changeLang := lang != ""
|
changeLang := lang != ""
|
||||||
|
@ -335,7 +337,7 @@ func locale(next echo.HandlerFunc) echo.HandlerFunc {
|
||||||
changeLang = false
|
changeLang = false
|
||||||
}
|
}
|
||||||
|
|
||||||
//3.Then check from 'Accept-Language' header.
|
// 3.Then check from 'Accept-Language' header.
|
||||||
if len(lang) == 0 {
|
if len(lang) == 0 {
|
||||||
tags, _, _ := language.ParseAcceptLanguage(ctx.Request().Header.Get("Accept-Language"))
|
tags, _, _ := language.ParseAcceptLanguage(ctx.Request().Header.Get("Accept-Language"))
|
||||||
lang = i18n.Locales.MatchTag(tags)
|
lang = i18n.Locales.MatchTag(tags)
|
||||||
|
|
|
@ -3,12 +3,13 @@ package web
|
||||||
import (
|
import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/labstack/echo/v4"
|
|
||||||
"github.com/thomiceli/opengist/internal/db"
|
|
||||||
"golang.org/x/crypto/ssh"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/thomiceli/opengist/internal/db"
|
||||||
|
"golang.org/x/crypto/ssh"
|
||||||
)
|
)
|
||||||
|
|
||||||
func userSettings(ctx echo.Context) error {
|
func userSettings(ctx echo.Context) error {
|
||||||
|
@ -62,7 +63,7 @@ func accountDeleteProcess(ctx echo.Context) error {
|
||||||
func sshKeysProcess(ctx echo.Context) error {
|
func sshKeysProcess(ctx echo.Context) error {
|
||||||
user := getUserLogged(ctx)
|
user := getUserLogged(ctx)
|
||||||
|
|
||||||
var dto = new(db.SSHKeyDTO)
|
dto := new(db.SSHKeyDTO)
|
||||||
if err := ctx.Bind(dto); err != nil {
|
if err := ctx.Bind(dto); err != nil {
|
||||||
return errorRes(400, "Cannot bind data", err)
|
return errorRes(400, "Cannot bind data", err)
|
||||||
}
|
}
|
||||||
|
@ -93,7 +94,6 @@ func sshKeysProcess(ctx echo.Context) error {
|
||||||
func sshKeysDelete(ctx echo.Context) error {
|
func sshKeysDelete(ctx echo.Context) error {
|
||||||
user := getUserLogged(ctx)
|
user := getUserLogged(ctx)
|
||||||
keyId, err := strconv.Atoi(ctx.Param("id"))
|
keyId, err := strconv.Atoi(ctx.Param("id"))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return redirect(ctx, "/settings")
|
return redirect(ctx, "/settings")
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
package test
|
package test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/thomiceli/opengist/internal/db"
|
"github.com/thomiceli/opengist/internal/db"
|
||||||
"github.com/thomiceli/opengist/internal/git"
|
"github.com/thomiceli/opengist/internal/git"
|
||||||
"testing"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGists(t *testing.T) {
|
func TestGists(t *testing.T) {
|
||||||
|
@ -110,7 +111,7 @@ func TestVisibility(t *testing.T) {
|
||||||
gist1 := db.GistDTO{
|
gist1 := db.GistDTO{
|
||||||
Title: "gist1",
|
Title: "gist1",
|
||||||
Description: "my first gist",
|
Description: "my first gist",
|
||||||
Private: 1,
|
Private: db.UnlistedVisibility,
|
||||||
Name: []string{""},
|
Name: []string{""},
|
||||||
Content: []string{"yeah"},
|
Content: []string{"yeah"},
|
||||||
}
|
}
|
||||||
|
@ -119,25 +120,25 @@ func TestVisibility(t *testing.T) {
|
||||||
|
|
||||||
gist1db, err := db.GetGistByID("1")
|
gist1db, err := db.GetGistByID("1")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, 1, gist1db.Private)
|
require.Equal(t, db.UnlistedVisibility, gist1db.Private)
|
||||||
|
|
||||||
err = s.request("POST", "/"+gist1db.User.Username+"/"+gist1db.Uuid+"/visibility", nil, 302)
|
err = s.request("POST", "/"+gist1db.User.Username+"/"+gist1db.Uuid+"/visibility", nil, 302)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
gist1db, err = db.GetGistByID("1")
|
gist1db, err = db.GetGistByID("1")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, 2, gist1db.Private)
|
require.Equal(t, db.PrivateVisibility, gist1db.Private)
|
||||||
|
|
||||||
err = s.request("POST", "/"+gist1db.User.Username+"/"+gist1db.Uuid+"/visibility", nil, 302)
|
err = s.request("POST", "/"+gist1db.User.Username+"/"+gist1db.Uuid+"/visibility", nil, 302)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
gist1db, err = db.GetGistByID("1")
|
gist1db, err = db.GetGistByID("1")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, 0, gist1db.Private)
|
require.Equal(t, db.PublicVisibility, gist1db.Private)
|
||||||
|
|
||||||
err = s.request("POST", "/"+gist1db.User.Username+"/"+gist1db.Uuid+"/visibility", nil, 302)
|
err = s.request("POST", "/"+gist1db.User.Username+"/"+gist1db.Uuid+"/visibility", nil, 302)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
gist1db, err = db.GetGistByID("1")
|
gist1db, err = db.GetGistByID("1")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, 1, gist1db.Private)
|
require.Equal(t, db.UnlistedVisibility, gist1db.Private)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLikeFork(t *testing.T) {
|
func TestLikeFork(t *testing.T) {
|
||||||
|
|
|
@ -154,12 +154,18 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||||
document.getElementById('gist-visibility-menu-button')!.onclick = () => {
|
document.getElementById('gist-visibility-menu-button')!.onclick = () => {
|
||||||
gistmenuvisibility!.classList.toggle('hidden');
|
gistmenuvisibility!.classList.toggle('hidden');
|
||||||
}
|
}
|
||||||
|
const lastVisibility = localStorage.getItem('visibility');
|
||||||
Array.from(document.querySelectorAll('.gist-visibility-option')).forEach((el) => {
|
Array.from(document.querySelectorAll('.gist-visibility-option')).forEach((el) => {
|
||||||
|
const visibility = (el as HTMLElement).dataset.visibility || '0';
|
||||||
(el as HTMLElement).onclick = () => {
|
(el as HTMLElement).onclick = () => {
|
||||||
submitgistbutton.textContent = (el as HTMLElement).dataset.btntext;
|
submitgistbutton.textContent = (el as HTMLElement).dataset.btntext;
|
||||||
submitgistbutton!.value = (el as HTMLElement).dataset.visibility || '0';
|
submitgistbutton!.value = visibility;
|
||||||
|
localStorage.setItem('visibility', visibility);
|
||||||
gistmenuvisibility!.classList.add('hidden');
|
gistmenuvisibility!.classList.add('hidden');
|
||||||
}
|
}
|
||||||
|
if (lastVisibility === visibility) {
|
||||||
|
(el as HTMLElement).click();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
2
templates/pages/edit.html
vendored
2
templates/pages/edit.html
vendored
|
@ -21,7 +21,7 @@
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M13.875 18.825A10.05 10.05 0 0112 19c-4.478 0-8.268-2.943-9.543-7a9.97 9.97 0 011.563-3.029m5.858.908a3 3 0 114.243 4.243M9.878 9.878l4.242 4.242M9.88 9.88l-3.29-3.29m7.532 7.532l3.29 3.29M3 3l3.59 3.59m0 0A9.953 9.953 0 0112 5c4.478 0 8.268 2.943 9.543 7a10.025 10.025 0 01-4.132 5.411m0 0L21 21" />
|
||||||
</svg>
|
</svg>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ .locale.Tr "gist.edit.change-visibility" }} {{ visibilityStr (inc .gist.Private) true }}
|
{{ .locale.Tr "gist.edit.change-visibility" }} {{ visibilityStr .gist.Private.Next true }}
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
<form id="delete" onsubmit="return confirm('Are you sure you want to delete this gist ?')" class="ml-2 flex items-center" method="post" action="/{{ .gist.User.Username }}/{{ .gist.Uuid }}/delete">
|
<form id="delete" onsubmit="return confirm('Are you sure you want to delete this gist ?')" class="ml-2 flex items-center" method="post" action="/{{ .gist.User.Username }}/{{ .gist.Uuid }}/delete">
|
||||||
|
|
Loading…
Reference in a new issue