| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- package panel
- import (
- "errors"
- "testing"
- "gorm.io/gorm"
- "github.com/mhsanaei/3x-ui/v3/internal/config"
- "github.com/mhsanaei/3x-ui/v3/internal/database"
- "github.com/mhsanaei/3x-ui/v3/internal/database/model"
- )
- var errInjectedTokenCreate = errors.New("injected token create failure")
- func TestApiTokenCreatedAtSeconds(t *testing.T) {
- tests := []struct {
- name string
- in int64
- want int64
- }{
- {name: "seconds", in: 1_782_485_394, want: 1_782_485_394},
- {name: "legacy milliseconds", in: 1_782_485_394_270, want: 1_782_485_394},
- {name: "unset", in: 0, want: 0},
- }
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- if got := apiTokenCreatedAtSeconds(tt.in); got != tt.want {
- t.Fatalf("apiTokenCreatedAtSeconds(%d) = %d, want %d", tt.in, got, tt.want)
- }
- })
- }
- }
- func TestRecreateByNamePreservesTokenWhenReplacementFails(t *testing.T) {
- t.Setenv("XUI_DB_FOLDER", t.TempDir())
- if err := database.InitDB(config.GetDBPath()); err != nil {
- t.Fatalf("init db: %v", err)
- }
- t.Cleanup(func() { _ = database.CloseDB() })
- svc := ApiTokenService{}
- first, err := svc.RecreateByName("cli-fallback")
- if err != nil {
- t.Fatalf("first recreate: %v", err)
- }
- db := database.GetDB()
- const callback = "test:fail-token-replacement"
- if err := db.Callback().Create().Before("gorm:create").Register(callback, func(tx *gorm.DB) {
- if token, ok := tx.Statement.Dest.(*model.ApiToken); ok && token.Name == "cli-fallback" {
- tx.AddError(errInjectedTokenCreate)
- }
- }); err != nil {
- t.Fatalf("register callback: %v", err)
- }
- t.Cleanup(func() { _ = db.Callback().Create().Remove(callback) })
- if _, err := svc.RecreateByName("cli-fallback"); !errors.Is(err, errInjectedTokenCreate) {
- t.Fatalf("recreate error = %v, want %v", err, errInjectedTokenCreate)
- }
- var row model.ApiToken
- if err := db.Where("name = ?", "cli-fallback").First(&row).Error; err != nil {
- t.Fatalf("load preserved token: %v", err)
- }
- if !svc.Match(first.Token) {
- t.Fatal("original token was revoked after replacement failure")
- }
- }
- func TestRecreateByNameKeepsOneToken(t *testing.T) {
- t.Setenv("XUI_DB_FOLDER", t.TempDir())
- if err := database.InitDB(config.GetDBPath()); err != nil {
- t.Fatalf("init db: %v", err)
- }
- t.Cleanup(func() { _ = database.CloseDB() })
- svc := ApiTokenService{}
- first, err := svc.RecreateByName("cli-fallback")
- if err != nil {
- t.Fatalf("first recreate: %v", err)
- }
- second, err := svc.RecreateByName("cli-fallback")
- if err != nil {
- t.Fatalf("second recreate: %v", err)
- }
- if first.Token == second.Token {
- t.Fatal("second call returned the same plaintext, want a rotated token")
- }
- var count int64
- if err := database.GetDB().Model(model.ApiToken{}).Where("name = ?", "cli-fallback").Count(&count).Error; err != nil {
- t.Fatalf("count: %v", err)
- }
- if count != 1 {
- t.Fatalf("token rows = %d, want 1", count)
- }
- }
|