Remove dead code
This commit is contained in:
parent
86cfdcff52
commit
8eaa27bb31
|
|
@ -8,7 +8,6 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
|
@ -199,9 +198,3 @@ func AppleAuthCodeOption() oauth2.AuthCodeOption {
|
||||||
return oauth2.SetAuthURLParam("response_mode", "form_post")
|
return oauth2.SetAuthURLParam("response_mode", "form_post")
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadAppleFormPost reads an Apple Sign In form_post callback.
|
|
||||||
func ReadAppleFormPost(body io.Reader) (code, state, userData string, err error) {
|
|
||||||
// Apple sends form_post so we need to read from the body
|
|
||||||
// This is handled by r.FormValue() in the handler
|
|
||||||
return "", "", "", nil
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -153,7 +153,3 @@ func (s *Service) CreateUserWithPassword(ctx context.Context, emailAddr, passwor
|
||||||
|
|
||||||
return &user, nil
|
return &user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) DB() *gorm.DB {
|
|
||||||
return s.db
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package config
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
|
@ -40,9 +39,6 @@ type Config struct {
|
||||||
AppleKeyID string
|
AppleKeyID string
|
||||||
AppleKeyPath string
|
AppleKeyPath string
|
||||||
|
|
||||||
// Admin
|
|
||||||
InitialAdminEmail string
|
|
||||||
TailscaleAllowedUsers []string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Load() (*Config, error) {
|
func Load() (*Config, error) {
|
||||||
|
|
@ -66,15 +62,6 @@ func Load() (*Config, error) {
|
||||||
AppleKeyPath: getEnv("APPLE_KEY_PATH", ""),
|
AppleKeyPath: getEnv("APPLE_KEY_PATH", ""),
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.InitialAdminEmail = getEnv("INITIAL_ADMIN_EMAIL", "")
|
|
||||||
|
|
||||||
if allowed := getEnv("TAILSCALE_ALLOWED_USERS", ""); allowed != "" {
|
|
||||||
cfg.TailscaleAllowedUsers = strings.Split(allowed, ",")
|
|
||||||
for i := range cfg.TailscaleAllowedUsers {
|
|
||||||
cfg.TailscaleAllowedUsers[i] = strings.TrimSpace(cfg.TailscaleAllowedUsers[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if cfg.DatabaseURL == "" {
|
if cfg.DatabaseURL == "" {
|
||||||
return nil, fmt.Errorf("DATABASE_URL is required")
|
return nil, fmt.Errorf("DATABASE_URL is required")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@ func clearConfigEnv(t *testing.T) {
|
||||||
"GOOGLE_CLIENT_ID", "GOOGLE_CLIENT_SECRET",
|
"GOOGLE_CLIENT_ID", "GOOGLE_CLIENT_SECRET",
|
||||||
"MICROSOFT_CLIENT_ID", "MICROSOFT_CLIENT_SECRET", "MICROSOFT_TENANT_ID",
|
"MICROSOFT_CLIENT_ID", "MICROSOFT_CLIENT_SECRET", "MICROSOFT_TENANT_ID",
|
||||||
"APPLE_CLIENT_ID", "APPLE_TEAM_ID", "APPLE_KEY_ID", "APPLE_KEY_PATH",
|
"APPLE_CLIENT_ID", "APPLE_TEAM_ID", "APPLE_KEY_ID", "APPLE_KEY_PATH",
|
||||||
"INITIAL_ADMIN_EMAIL",
|
|
||||||
}
|
}
|
||||||
for _, v := range envVars {
|
for _, v := range envVars {
|
||||||
os.Unsetenv(v)
|
os.Unsetenv(v)
|
||||||
|
|
@ -114,57 +113,3 @@ func TestLoad_OverrideDefaults(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLoad_InitialAdminEmail(t *testing.T) {
|
|
||||||
clearConfigEnv(t)
|
|
||||||
t.Setenv("DATABASE_URL", "postgres://localhost/test")
|
|
||||||
t.Setenv("SESSION_SECRET", "test-session-secret-that-is-32ch")
|
|
||||||
t.Setenv("INITIAL_ADMIN_EMAIL", "admin@example.com")
|
|
||||||
|
|
||||||
cfg, err := Load()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("expected no error, got: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if cfg.InitialAdminEmail != "admin@example.com" {
|
|
||||||
t.Errorf("expected InitialAdminEmail %q, got %q", "admin@example.com", cfg.InitialAdminEmail)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLoad_TailscaleAllowedUsers(t *testing.T) {
|
|
||||||
clearConfigEnv(t)
|
|
||||||
t.Setenv("DATABASE_URL", "postgres://localhost/test")
|
|
||||||
t.Setenv("SESSION_SECRET", "test-session-secret-that-is-32ch")
|
|
||||||
t.Setenv("TAILSCALE_ALLOWED_USERS", "alice@example.com, bob@example.com , charlie@example.com")
|
|
||||||
|
|
||||||
cfg, err := Load()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("expected no error, got: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(cfg.TailscaleAllowedUsers) != 3 {
|
|
||||||
t.Fatalf("expected 3 tailscale users, got %d", len(cfg.TailscaleAllowedUsers))
|
|
||||||
}
|
|
||||||
|
|
||||||
expected := []string{"alice@example.com", "bob@example.com", "charlie@example.com"}
|
|
||||||
for i, want := range expected {
|
|
||||||
if cfg.TailscaleAllowedUsers[i] != want {
|
|
||||||
t.Errorf("TailscaleAllowedUsers[%d]: expected %q, got %q", i, want, cfg.TailscaleAllowedUsers[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestLoad_EmptyTailscaleAllowedUsers(t *testing.T) {
|
|
||||||
clearConfigEnv(t)
|
|
||||||
t.Setenv("DATABASE_URL", "postgres://localhost/test")
|
|
||||||
t.Setenv("SESSION_SECRET", "test-session-secret-that-is-32ch")
|
|
||||||
// TAILSCALE_ALLOWED_USERS not set
|
|
||||||
|
|
||||||
cfg, err := Load()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("expected no error, got: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if cfg.TailscaleAllowedUsers != nil {
|
|
||||||
t.Errorf("expected nil TailscaleAllowedUsers, got %v", cfg.TailscaleAllowedUsers)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -39,11 +39,6 @@ func (c *Client) BaseURL() string {
|
||||||
return c.baseURL
|
return c.baseURL
|
||||||
}
|
}
|
||||||
|
|
||||||
// APIToken returns the API token for authenticated proxy requests.
|
|
||||||
func (c *Client) APIToken() string {
|
|
||||||
return c.apiToken
|
|
||||||
}
|
|
||||||
|
|
||||||
type CreateIssueRequest struct {
|
type CreateIssueRequest struct {
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
Body string `json:"body"`
|
Body string `json:"body"`
|
||||||
|
|
@ -111,14 +106,6 @@ func (u APIUser) DisplayName() string {
|
||||||
return u.Login
|
return u.Login
|
||||||
}
|
}
|
||||||
|
|
||||||
type CommentView struct {
|
|
||||||
Body string
|
|
||||||
AuthorName string
|
|
||||||
IsTeam bool
|
|
||||||
CreatedAt time.Time
|
|
||||||
Attachments []Attachment
|
|
||||||
}
|
|
||||||
|
|
||||||
// TimelineEvent represents a single event in the issue timeline from Forgejo.
|
// TimelineEvent represents a single event in the issue timeline from Forgejo.
|
||||||
type TimelineEvent struct {
|
type TimelineEvent struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
|
|
@ -201,39 +188,6 @@ func StripCommentFooter(body string) (string, string) {
|
||||||
return cleanBody, ""
|
return cleanBody, ""
|
||||||
}
|
}
|
||||||
|
|
||||||
// BuildCommentViews transforms Forgejo comments into view models,
|
|
||||||
// identifying customer vs team comments.
|
|
||||||
func BuildCommentViews(comments []Comment, botLogin string) []CommentView {
|
|
||||||
var views []CommentView
|
|
||||||
for _, c := range comments {
|
|
||||||
body, email := StripCommentFooter(c.Body)
|
|
||||||
isCustomer := email != "" || (botLogin != "" && c.User.Login == botLogin)
|
|
||||||
|
|
||||||
if isCustomer {
|
|
||||||
authorName := email
|
|
||||||
if authorName == "" {
|
|
||||||
authorName = "Customer"
|
|
||||||
}
|
|
||||||
views = append(views, CommentView{
|
|
||||||
Body: body,
|
|
||||||
AuthorName: authorName,
|
|
||||||
IsTeam: false,
|
|
||||||
CreatedAt: c.CreatedAt,
|
|
||||||
Attachments: c.Assets,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
views = append(views, CommentView{
|
|
||||||
Body: c.Body,
|
|
||||||
AuthorName: c.User.DisplayName(),
|
|
||||||
IsTeam: true,
|
|
||||||
CreatedAt: c.CreatedAt,
|
|
||||||
Attachments: c.Assets,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return views
|
|
||||||
}
|
|
||||||
|
|
||||||
// BuildTimelineViews converts raw timeline events into template-friendly views.
|
// BuildTimelineViews converts raw timeline events into template-friendly views.
|
||||||
func BuildTimelineViews(events []TimelineEvent, botLogin string, isAdmin bool) []TimelineView {
|
func BuildTimelineViews(events []TimelineEvent, botLogin string, isAdmin bool) []TimelineView {
|
||||||
var views []TimelineView
|
var views []TimelineView
|
||||||
|
|
@ -332,21 +286,6 @@ func ExtractIssueReferences(text string) []int64 {
|
||||||
return refs
|
return refs
|
||||||
}
|
}
|
||||||
|
|
||||||
// SortIssuesPinnedFirst sorts issues with pinned (PinOrder > 0) first, then by CreatedAt desc.
|
|
||||||
func SortIssuesPinnedFirst(issues []Issue) {
|
|
||||||
sort.SliceStable(issues, func(i, j int) bool {
|
|
||||||
iPinned := issues[i].PinOrder > 0
|
|
||||||
jPinned := issues[j].PinOrder > 0
|
|
||||||
if iPinned != jPinned {
|
|
||||||
return iPinned
|
|
||||||
}
|
|
||||||
if iPinned && jPinned {
|
|
||||||
return issues[i].PinOrder < issues[j].PinOrder
|
|
||||||
}
|
|
||||||
return issues[i].CreatedAt.After(issues[j].CreatedAt)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func GenerateWebhookSecret() (string, error) {
|
func GenerateWebhookSecret() (string, error) {
|
||||||
b := make([]byte, 32)
|
b := make([]byte, 32)
|
||||||
if _, err := rand.Read(b); err != nil {
|
if _, err := rand.Read(b); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -18,11 +18,8 @@ var (
|
||||||
md goldmark.Markdown
|
md goldmark.Markdown
|
||||||
policy *bluemonday.Policy
|
policy *bluemonday.Policy
|
||||||
|
|
||||||
// Matches @username in rendered HTML text (not inside tags)
|
|
||||||
mentionRegex = regexp.MustCompile(`(?:^|[\s(>])(@(\w+))`)
|
|
||||||
|
|
||||||
// Matches @username in raw markdown for extraction
|
// Matches @username in raw markdown for extraction
|
||||||
RawMentionRegex = regexp.MustCompile(`(?:^|[\s(])@(\w+)`)
|
rawMentionRegex = regexp.MustCompile(`(?:^|[\s(])@(\w+)`)
|
||||||
|
|
||||||
// Matches :shortcode: patterns for emoji replacement
|
// Matches :shortcode: patterns for emoji replacement
|
||||||
emojiRegex = regexp.MustCompile(`:(\w+):`)
|
emojiRegex = regexp.MustCompile(`:(\w+):`)
|
||||||
|
|
@ -394,7 +391,7 @@ func ExtractMentions(texts ...string) []string {
|
||||||
seen := map[string]bool{}
|
seen := map[string]bool{}
|
||||||
var result []string
|
var result []string
|
||||||
for _, text := range texts {
|
for _, text := range texts {
|
||||||
for _, m := range RawMentionRegex.FindAllStringSubmatch(text, -1) {
|
for _, m := range rawMentionRegex.FindAllStringSubmatch(text, -1) {
|
||||||
username := m[1]
|
username := m[1]
|
||||||
if !seen[username] {
|
if !seen[username] {
|
||||||
seen[username] = true
|
seen[username] = true
|
||||||
|
|
|
||||||
|
|
@ -19,16 +19,6 @@ func RequestID(c *gin.Context) {
|
||||||
c.Next()
|
c.Next()
|
||||||
}
|
}
|
||||||
|
|
||||||
type responseWriter struct {
|
|
||||||
http.ResponseWriter
|
|
||||||
status int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rw *responseWriter) WriteHeader(code int) {
|
|
||||||
rw.status = code
|
|
||||||
rw.ResponseWriter.WriteHeader(code)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Logging(c *gin.Context) {
|
func Logging(c *gin.Context) {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
c.Next()
|
c.Next()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue