From 1bd0807d6579d5f0b17e123dcbad4f5640e861bc Mon Sep 17 00:00:00 2001 From: LittleSheep Date: Wed, 20 Mar 2024 20:56:07 +0800 Subject: [PATCH] :sparkles: Banner --- pkg/grpc/proto/auth.pb.go | 76 +++++++++++++---------- pkg/grpc/proto/auth.proto | 3 +- pkg/grpc/server.go | 10 +-- pkg/models/accounts.go | 11 +++- pkg/server/avatar_api.go | 50 ++++++++++++++- pkg/server/startup.go | 30 +++++---- pkg/views/src/layouts/master.vue | 2 +- pkg/views/src/layouts/user-center.vue | 4 +- pkg/views/src/views/personalize.vue | 89 +++++++++++++++++++-------- 9 files changed, 196 insertions(+), 79 deletions(-) diff --git a/pkg/grpc/proto/auth.pb.go b/pkg/grpc/proto/auth.pb.go index 0d59127..1870972 100644 --- a/pkg/grpc/proto/auth.pb.go +++ b/pkg/grpc/proto/auth.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.32.0 +// protoc-gen-go v1.33.0 // protoc v4.25.3 // source: auth.proto @@ -30,7 +30,8 @@ type Userinfo struct { Nick string `protobuf:"bytes,3,opt,name=nick,proto3" json:"nick,omitempty"` Email string `protobuf:"bytes,4,opt,name=email,proto3" json:"email,omitempty"` Avatar string `protobuf:"bytes,5,opt,name=avatar,proto3" json:"avatar,omitempty"` - Description *string `protobuf:"bytes,6,opt,name=description,proto3,oneof" json:"description,omitempty"` + Banner string `protobuf:"bytes,6,opt,name=banner,proto3" json:"banner,omitempty"` + Description *string `protobuf:"bytes,7,opt,name=description,proto3,oneof" json:"description,omitempty"` } func (x *Userinfo) Reset() { @@ -100,6 +101,13 @@ func (x *Userinfo) GetAvatar() string { return "" } +func (x *Userinfo) GetBanner() string { + if x != nil { + return x.Banner + } + return "" +} + func (x *Userinfo) GetDescription() string { if x != nil && x.Description != nil { return *x.Description @@ -237,43 +245,45 @@ var File_auth_proto protoreflect.FileDescriptor var file_auth_proto_rawDesc = []byte{ 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x22, 0xa7, 0x01, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x69, 0x6e, 0x66, 0x6f, + 0x6f, 0x74, 0x6f, 0x22, 0xbf, 0x01, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x69, 0x6e, 0x66, 0x6f, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x69, 0x63, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x69, 0x63, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x12, 0x25, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x64, - 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x0e, 0x0a, - 0x0c, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x6c, 0x0a, - 0x0b, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, - 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, - 0x28, 0x0a, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0c, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, - 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x72, 0x65, - 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xda, 0x01, 0x0a, 0x09, - 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, - 0x76, 0x61, 0x6c, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x56, - 0x61, 0x6c, 0x69, 0x64, 0x12, 0x26, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x61, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x28, 0x0a, 0x0d, - 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x0c, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, - 0x6b, 0x65, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x30, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x69, 0x6e, - 0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2e, 0x55, 0x73, 0x65, 0x72, 0x69, 0x6e, 0x66, 0x6f, 0x48, 0x02, 0x52, 0x08, 0x75, 0x73, 0x65, - 0x72, 0x69, 0x6e, 0x66, 0x6f, 0x88, 0x01, 0x01, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x61, 0x63, 0x63, - 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x72, 0x65, - 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x42, 0x0b, 0x0a, 0x09, 0x5f, - 0x75, 0x73, 0x65, 0x72, 0x69, 0x6e, 0x66, 0x6f, 0x32, 0x3e, 0x0a, 0x04, 0x41, 0x75, 0x74, 0x68, - 0x12, 0x36, 0x0a, 0x0c, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x12, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x75, 0x74, - 0x68, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x09, 0x5a, 0x07, 0x2e, 0x3b, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x61, 0x6e, 0x6e, 0x65, 0x72, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x25, + 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x6c, 0x0a, 0x0b, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, + 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, + 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x28, 0x0a, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, + 0x73, 0x68, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, + 0x52, 0x0c, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x88, 0x01, + 0x01, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x22, 0xda, 0x01, 0x0a, 0x09, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x70, 0x6c, + 0x79, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x07, 0x69, 0x73, 0x56, 0x61, 0x6c, 0x69, 0x64, 0x12, 0x26, 0x0a, 0x0c, + 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, + 0x6e, 0x88, 0x01, 0x01, 0x12, 0x28, 0x0a, 0x0d, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01, 0x52, 0x0c, 0x72, + 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x30, + 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x0f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x69, 0x6e, 0x66, + 0x6f, 0x48, 0x02, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x69, 0x6e, 0x66, 0x6f, 0x88, 0x01, 0x01, + 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x5f, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x69, 0x6e, 0x66, 0x6f, + 0x32, 0x3e, 0x0a, 0x04, 0x41, 0x75, 0x74, 0x68, 0x12, 0x36, 0x0a, 0x0c, 0x41, 0x75, 0x74, 0x68, + 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, + 0x42, 0x09, 0x5a, 0x07, 0x2e, 0x3b, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( diff --git a/pkg/grpc/proto/auth.proto b/pkg/grpc/proto/auth.proto index d9aa54f..456dd2b 100644 --- a/pkg/grpc/proto/auth.proto +++ b/pkg/grpc/proto/auth.proto @@ -14,7 +14,8 @@ message Userinfo { string nick = 3; string email = 4; string avatar = 5; - optional string description = 6; + string banner = 6; + optional string description = 7; } message AuthRequest { diff --git a/pkg/grpc/server.go b/pkg/grpc/server.go index ddbec31..7353b15 100644 --- a/pkg/grpc/server.go +++ b/pkg/grpc/server.go @@ -1,16 +1,17 @@ package grpc import ( + "context" + "fmt" + "net" + "code.smartsheep.studio/hydrogen/identity/pkg/grpc/proto" "code.smartsheep.studio/hydrogen/identity/pkg/models" "code.smartsheep.studio/hydrogen/identity/pkg/services" - "context" - "fmt" "github.com/samber/lo" "github.com/spf13/viper" "google.golang.org/grpc" "google.golang.org/grpc/reflection" - "net" ) type Server struct { @@ -35,7 +36,8 @@ func (v *Server) Authenticate(_ context.Context, in *proto.AuthRequest) (*proto. Nick: user.Nick, Email: user.GetPrimaryEmail().Content, Avatar: fmt.Sprintf("https://%s/api/avatar/%s", viper.GetString("domain"), user.Avatar), - Description: nil, + Banner: fmt.Sprintf("https://%s/api/avatar/%s", viper.GetString("domain"), user.Banner), + Description: &user.Description, }, }, nil } diff --git a/pkg/models/accounts.go b/pkg/models/accounts.go index 56f635f..7d0a962 100644 --- a/pkg/models/accounts.go +++ b/pkg/models/accounts.go @@ -1,10 +1,11 @@ package models import ( - "github.com/samber/lo" - "github.com/spf13/viper" "path/filepath" "time" + + "github.com/samber/lo" + "github.com/spf13/viper" ) type Account struct { @@ -14,6 +15,7 @@ type Account struct { Nick string `json:"nick"` Description string `json:"description"` Avatar string `json:"avatar"` + Banner string `json:"banner"` Profile AccountProfile `json:"profile"` Sessions []AuthSession `json:"sessions"` Challenges []AuthChallenge `json:"challenges"` @@ -40,6 +42,11 @@ func (v Account) GetAvatarPath() string { return filepath.Join(basepath, v.Avatar) } +func (v Account) GetBannerPath() string { + basepath := viper.GetString("content") + return filepath.Join(basepath, v.Banner) +} + type AccountContactType = int8 const ( diff --git a/pkg/server/avatar_api.go b/pkg/server/avatar_api.go index 474e543..1f0e3ad 100644 --- a/pkg/server/avatar_api.go +++ b/pkg/server/avatar_api.go @@ -1,12 +1,14 @@ package server import ( + "os" + "path/filepath" + "code.smartsheep.studio/hydrogen/identity/pkg/database" "code.smartsheep.studio/hydrogen/identity/pkg/models" "github.com/gofiber/fiber/v2" "github.com/google/uuid" "github.com/spf13/viper" - "path/filepath" ) func getAvatar(c *fiber.Ctx) error { @@ -23,12 +25,58 @@ func setAvatar(c *fiber.Ctx) error { return err } + var previous string + if len(user.Avatar) > 0 { + previous = user.GetAvatarPath() + } + user.Avatar = uuid.NewString() if err := c.SaveFile(file, user.GetAvatarPath()); err != nil { return err } else { database.C.Save(&user) + + // Clean up + if len(previous) > 0 { + basepath := viper.GetString("content") + filepath := filepath.Join(basepath, previous) + if info, err := os.Stat(filepath); err == nil && !info.IsDir() { + os.Remove(filepath) + } + } + } + + return c.SendStatus(fiber.StatusOK) +} + +func setBanner(c *fiber.Ctx) error { + user := c.Locals("principal").(models.Account) + file, err := c.FormFile("banner") + if err != nil { + return err + } + + var previous string + if len(user.Banner) > 0 { + previous = user.GetBannerPath() + } + + user.Banner = uuid.NewString() + + if err := c.SaveFile(file, user.GetBannerPath()); err != nil { + return err + } else { + database.C.Save(&user) + + // Clean up + if len(previous) > 0 { + basepath := viper.GetString("content") + filepath := filepath.Join(basepath, previous) + if info, err := os.Stat(filepath); err == nil && !info.IsDir() { + os.Remove(filepath) + } + } } return c.SendStatus(fiber.StatusOK) diff --git a/pkg/server/startup.go b/pkg/server/startup.go index f465083..839b324 100644 --- a/pkg/server/startup.go +++ b/pkg/server/startup.go @@ -1,6 +1,10 @@ package server import ( + "net/http" + "strings" + "time" + "code.smartsheep.studio/hydrogen/identity/pkg/views" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/cache" @@ -11,9 +15,6 @@ import ( jsoniter "github.com/json-iterator/go" "github.com/rs/zerolog/log" "github.com/spf13/viper" - "net/http" - "strings" - "time" ) var A *fiber.App @@ -58,21 +59,28 @@ func NewServer() { api := A.Group("/api").Name("API") { api.Get("/avatar/:avatarId", getAvatar) - api.Put("/avatar", authMiddleware, setAvatar) api.Get("/notifications", authMiddleware, getNotifications) api.Put("/notifications/:notificationId/read", authMiddleware, markNotificationRead) api.Post("/notifications/subscribe", authMiddleware, addNotifySubscriber) - api.Get("/users/me", authMiddleware, getUserinfo) - api.Put("/users/me", authMiddleware, editUserinfo) - api.Get("/users/me/events", authMiddleware, getEvents) - api.Get("/users/me/challenges", authMiddleware, getChallenges) - api.Get("/users/me/sessions", authMiddleware, getSessions) - api.Delete("/users/me/sessions/:sessionId", authMiddleware, killSession) + me := api.Group("/users/me").Name("Myself Operations") + { + + me.Put("/avatar", authMiddleware, setAvatar) + me.Put("/banner", authMiddleware, setBanner) + + me.Get("/", authMiddleware, getUserinfo) + me.Put("/", authMiddleware, editUserinfo) + me.Get("/events", authMiddleware, getEvents) + me.Get("/challenges", authMiddleware, getChallenges) + me.Get("/sessions", authMiddleware, getSessions) + me.Delete("/sessions/:sessionId", authMiddleware, killSession) + + me.Post("/confirm", doRegisterConfirm) + } api.Post("/users", doRegister) - api.Post("/users/me/confirm", doRegisterConfirm) api.Put("/auth", startChallenge) api.Post("/auth", doChallenge) diff --git a/pkg/views/src/layouts/master.vue b/pkg/views/src/layouts/master.vue index b42830b..4b1d5c9 100644 --- a/pkg/views/src/layouts/master.vue +++ b/pkg/views/src/layouts/master.vue @@ -2,7 +2,7 @@
- +

Solarpass

diff --git a/pkg/views/src/layouts/user-center.vue b/pkg/views/src/layouts/user-center.vue index 437106f..407452c 100644 --- a/pkg/views/src/layouts/user-center.vue +++ b/pkg/views/src/layouts/user-center.vue @@ -1,7 +1,7 @@