feat(auth): add user profile, phone login, and account deletion

This commit is contained in:
iu
2026-10-12 14:26:32 +03:00
parent 1cb9aaf198
commit 86aff695df
46 changed files with 2893 additions and 134 deletions
+18
View File
@@ -5,6 +5,7 @@ import "time"
type User struct {
ID string `json:"id"`
Email string `json:"email"`
Phone string `json:"phone,omitempty"`
PasswordHash string `json:"-"`
Name string `json:"name"`
AvatarURL string `json:"avatar_url,omitempty"`
@@ -26,6 +27,23 @@ func (u *User) Public() PublicUser {
return PublicUser{ID: u.ID, Email: u.Email, Name: u.Name, AvatarURL: u.AvatarURL}
}
// SelfUser is the owner-facing representation of an account. Unlike PublicUser
// it carries the phone number, which must never appear in public views.
type SelfUser struct {
ID string `json:"id"`
Email string `json:"email,omitempty"`
Phone string `json:"phone,omitempty"`
Name string `json:"name"`
AvatarURL string `json:"avatar_url,omitempty"`
}
func (u *User) Self() SelfUser {
if u == nil {
return SelfUser{}
}
return SelfUser{ID: u.ID, Email: u.Email, Phone: u.Phone, Name: u.Name, AvatarURL: u.AvatarURL}
}
type Album struct {
ID string `json:"id"`
OwnerID string `json:"owner_id"`
+30
View File
@@ -0,0 +1,30 @@
package models
import (
"encoding/json"
"strings"
"testing"
)
func TestPublicUserOmitsPhone(t *testing.T) {
u := &User{ID: "u1", Email: "user@test.local", Phone: "+15551234567", Name: "Tester"}
pub, err := json.Marshal(u.Public())
if err != nil {
t.Fatalf("marshal public: %v", err)
}
if strings.Contains(string(pub), "phone") || strings.Contains(string(pub), "+15551234567") {
t.Fatalf("PublicUser leaks phone: %s", pub)
}
self, err := json.Marshal(u.Self())
if err != nil {
t.Fatalf("marshal self: %v", err)
}
if !strings.Contains(string(self), "+15551234567") {
t.Fatalf("SelfUser missing phone: %s", self)
}
if !strings.Contains(string(self), `"phone"`) {
t.Fatalf("SelfUser phone not serialized: %s", self)
}
}