diff --git a/go.mod b/go.mod index 8107b91..5055c2a 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( github.com/tidwall/gjson v1.9.3 github.com/urfave/cli/v2 v2.4.0 golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 + golang.org/x/exp v0.0.0-20220414153411-bcd21879b8fd ) require ( diff --git a/go.sum b/go.sum index de3aec9..51292df 100644 --- a/go.sum +++ b/go.sum @@ -12,11 +12,8 @@ github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/gookit/color v1.5.0 h1:1Opow3+BWDwqor78DcJkJCIwnkviFi+rrOANki9BUFw= github.com/gookit/color v1.5.0/go.mod h1:43aQb+Zerm/BWh2GnrgOQm7ffz7tvQXEKV6BFMl7wAo= -github.com/gookit/goutil v0.4.4/go.mod h1:qlGVh0PI+WnWSjYnIocfz/7tkeogxL6+EDNP1mRe+7o= github.com/gookit/goutil v0.5.0 h1:SrbfjqZ8iprxJOfKZVT0yGJ4/82afr4Qa0RQwON19I4= github.com/gookit/goutil v0.5.0/go.mod h1:pq1eTibwb2wN96jrci0xy7xogWzzo9CihOQJEAvz4yQ= -github.com/gookit/slog v0.2.1 h1:EI47PlvpoPwxwkNTYaevN6iBNjo9nBxo0aQLiq+MTdk= -github.com/gookit/slog v0.2.1/go.mod h1:CsbWzAaZA2FjLuGzvfTAR/QvFisZG31deOcZ05H++NI= github.com/gookit/slog v0.2.2-0.20220415153407-dd89ed7b0448 h1:7kNDAgYDAu/5X+PbFfzGToaKJiDcghKv7B4XOGosrPM= github.com/gookit/slog v0.2.2-0.20220415153407-dd89ed7b0448/go.mod h1:9Sh1Utw3LVG0kqN++ankdfrCVQ7yixKDL1+YrYvIulU= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -57,6 +54,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M= golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20220414153411-bcd21879b8fd h1:zVFyTKZN/Q7mNRWSs1GOYnHM9NiFSJ54YVRsD0rNWT4= +golang.org/x/exp v0.0.0-20220414153411-bcd21879b8fd/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/internal/browingdata/bookmark.go b/internal/browingdata/bookmark.go index 35f7925..ec2a17c 100644 --- a/internal/browingdata/bookmark.go +++ b/internal/browingdata/bookmark.go @@ -10,8 +10,8 @@ import ( "hack-browser-data/internal/item" "hack-browser-data/internal/log" - "hack-browser-data/internal/utils" "hack-browser-data/internal/utils/fileutil" + "hack-browser-data/internal/utils/typeutil" _ "github.com/mattn/go-sqlite3" ) @@ -61,7 +61,7 @@ func getBookmarkChildren(value gjson.Result, w *ChromiumBookmark) (children gjso ID: value.Get(bookmarkID).Int(), Name: value.Get(bookmarkName).String(), URL: value.Get(bookmarkUrl).String(), - DateAdded: utils.TimeEpochFormat(value.Get(bookmarkAdded).Int()), + DateAdded: typeutil.TimeEpoch(value.Get(bookmarkAdded).Int()), } children = value.Get(bookmarkChildren) if nodeType.Exists() { @@ -114,9 +114,9 @@ func (f *FirefoxBookmark) Parse(masterKey []byte) error { *f = append(*f, bookmark{ ID: id, Name: title, - Type: utils.BookmarkType(bType), + Type: bookmarkType(bType), URL: url, - DateAdded: utils.TimeStampFormat(dateAdded / 1000000), + DateAdded: typeutil.TimeStamp(dateAdded / 1000000), }) } sort.Slice(*f, func(i, j int) bool { @@ -128,3 +128,12 @@ func (f *FirefoxBookmark) Parse(masterKey []byte) error { func (f *FirefoxBookmark) Name() string { return "bookmark" } + +func bookmarkType(a int64) string { + switch a { + case 1: + return "url" + default: + return "folder" + } +} diff --git a/internal/browingdata/cookie.go b/internal/browingdata/cookie.go index 515b564..8ea4252 100644 --- a/internal/browingdata/cookie.go +++ b/internal/browingdata/cookie.go @@ -10,7 +10,7 @@ import ( "hack-browser-data/internal/decrypter" "hack-browser-data/internal/item" "hack-browser-data/internal/log" - "hack-browser-data/internal/utils" + "hack-browser-data/internal/utils/typeutil" ) type ChromiumCookie []cookie @@ -43,12 +43,12 @@ func (c *ChromiumCookie) Parse(masterKey []byte) error { Host: host, Path: path, encryptValue: encryptValue, - IsSecure: utils.IntToBool(isSecure), - IsHTTPOnly: utils.IntToBool(isHTTPOnly), - HasExpire: utils.IntToBool(hasExpire), - IsPersistent: utils.IntToBool(isPersistent), - CreateDate: utils.TimeEpochFormat(createDate), - ExpireDate: utils.TimeEpochFormat(expireDate), + IsSecure: typeutil.IntToBool(isSecure), + IsHTTPOnly: typeutil.IntToBool(isHTTPOnly), + HasExpire: typeutil.IntToBool(hasExpire), + IsPersistent: typeutil.IntToBool(isPersistent), + CreateDate: typeutil.TimeEpoch(createDate), + ExpireDate: typeutil.TimeEpoch(expireDate), } // TODO: replace DPAPI if len(encryptValue) > 0 { @@ -102,10 +102,10 @@ func (f *FirefoxCookie) Parse(masterKey []byte) error { KeyName: name, Host: host, Path: path, - IsSecure: utils.IntToBool(isSecure), - IsHTTPOnly: utils.IntToBool(isHttpOnly), - CreateDate: utils.TimeStampFormat(creationTime / 1000000), - ExpireDate: utils.TimeStampFormat(expiry), + IsSecure: typeutil.IntToBool(isSecure), + IsHTTPOnly: typeutil.IntToBool(isHttpOnly), + CreateDate: typeutil.TimeStamp(creationTime / 1000000), + ExpireDate: typeutil.TimeStamp(expiry), Value: value, }) } diff --git a/internal/browingdata/download.go b/internal/browingdata/download.go index 0419f90..8761bd8 100644 --- a/internal/browingdata/download.go +++ b/internal/browingdata/download.go @@ -8,7 +8,7 @@ import ( "hack-browser-data/internal/item" "hack-browser-data/internal/log" - "hack-browser-data/internal/utils" + "hack-browser-data/internal/utils/typeutil" _ "github.com/mattn/go-sqlite3" "github.com/tidwall/gjson" @@ -40,8 +40,8 @@ func (c *ChromiumDownload) Parse(masterKey []byte) error { TargetPath: targetPath, Url: tabUrl, TotalBytes: totalBytes, - StartTime: utils.TimeEpochFormat(startTime), - EndTime: utils.TimeEpochFormat(endTime), + StartTime: typeutil.TimeEpoch(startTime), + EndTime: typeutil.TimeEpoch(endTime), MimeType: mimeType, } *c = append(*c, data) @@ -98,8 +98,8 @@ func (f *FirefoxDownload) Parse(masterKey []byte) error { TargetPath: path, Url: url, TotalBytes: fileSize.Int(), - StartTime: utils.TimeStampFormat(dateAdded / 1000000), - EndTime: utils.TimeStampFormat(endTime.Int() / 1000), + StartTime: typeutil.TimeStamp(dateAdded / 1000000), + EndTime: typeutil.TimeStamp(endTime.Int() / 1000), }) } } diff --git a/internal/browingdata/history.go b/internal/browingdata/history.go index e9dfdab..c7fb322 100644 --- a/internal/browingdata/history.go +++ b/internal/browingdata/history.go @@ -9,7 +9,7 @@ import ( "hack-browser-data/internal/item" "hack-browser-data/internal/log" - "hack-browser-data/internal/utils" + "hack-browser-data/internal/utils/typeutil" ) type ChromiumHistory []history @@ -40,7 +40,7 @@ func (c *ChromiumHistory) Parse(masterKey []byte) error { Url: url, Title: title, VisitCount: visitCount, - LastVisitTime: utils.TimeEpochFormat(lastVisitTime), + LastVisitTime: typeutil.TimeEpoch(lastVisitTime), } *c = append(*c, data) } @@ -91,7 +91,7 @@ func (f *FirefoxHistory) Parse(masterKey []byte) error { Title: title, Url: url, VisitCount: visitCount, - LastVisitTime: utils.TimeStampFormat(visitDate / 1000000), + LastVisitTime: typeutil.TimeStamp(visitDate / 1000000), }) } sort.Slice(*f, func(i, j int) bool { diff --git a/internal/browingdata/password.go b/internal/browingdata/password.go index 8652792..d4b2110 100644 --- a/internal/browingdata/password.go +++ b/internal/browingdata/password.go @@ -15,7 +15,7 @@ import ( "hack-browser-data/internal/decrypter" "hack-browser-data/internal/item" "hack-browser-data/internal/log" - "hack-browser-data/internal/utils" + "hack-browser-data/internal/utils/typeutil" ) type ChromiumPassword []loginData @@ -59,9 +59,9 @@ func (c *ChromiumPassword) Parse(masterKey []byte) error { } } if create > time.Now().Unix() { - login.CreateDate = utils.TimeEpochFormat(create) + login.CreateDate = typeutil.TimeEpoch(create) } else { - login.CreateDate = utils.TimeStampFormat(create) + login.CreateDate = typeutil.TimeStamp(create) } login.Password = string(password) *c = append(*c, login) @@ -119,9 +119,9 @@ func (c *YandexPassword) Parse(masterKey []byte) error { } } if create > time.Now().Unix() { - login.CreateDate = utils.TimeEpochFormat(create) + login.CreateDate = typeutil.TimeEpoch(create) } else { - login.CreateDate = utils.TimeStampFormat(create) + login.CreateDate = typeutil.TimeStamp(create) } login.Password = string(password) *c = append(*c, login) @@ -252,7 +252,7 @@ func getFirefoxLoginData(loginJson string) (l []loginData, err error) { } m.encryptUser = user m.encryptPass = pass - m.CreateDate = utils.TimeStampFormat(v.Get("timeCreated").Int() / 1000) + m.CreateDate = typeutil.TimeStamp(v.Get("timeCreated").Int() / 1000) l = append(l, m) } } diff --git a/internal/browser/browser.go b/internal/browser/browser.go index 08c203b..11ee860 100644 --- a/internal/browser/browser.go +++ b/internal/browser/browser.go @@ -43,7 +43,7 @@ func pickChromium(name, profile string) []Browser { if name == "all" { for _, v := range chromiumList { if b, err := chromium.New(v.name, v.storage, v.profilePath, v.items); err == nil { - log.Infof("find browser %s success", b.Name()) + log.Noticef("find browser %s success", b.Name()) browsers = append(browsers, b) } else { // TODO: show which browser find failed @@ -85,12 +85,12 @@ func pickFirefox(name, profile string) []Browser { } if multiFirefox, err := firefox.New(v.name, v.storage, profile, v.items); err == nil { for _, b := range multiFirefox { - log.Infof("find browser: %s success", b.Name()) + log.Noticef("find browser: firefox %s success", b.Name()) browsers = append(browsers, b) } } else { if strings.Contains(err.Error(), "profile path is not exist") { - log.Infof("find browser: %s failed, profile path is not exist", v.name) + log.Noticef("find browser: firefox %s failed, profile path is not exist", v.name) } else { log.Error(err) } diff --git a/internal/browser/browser_linux.go b/internal/browser/browser_linux.go index 9ba39bf..08ca83f 100644 --- a/internal/browser/browser_linux.go +++ b/internal/browser/browser_linux.go @@ -74,7 +74,7 @@ var ( firefoxProfilePath = homeDir + "/.mozilla/firefox/" chromeProfilePath = homeDir + "/.config/google-chrome/Default/" chromiumProfilePath = homeDir + "/.config/chromium/Default/" - edgeProfilePath = homeDir + "/.config/microsoft-edge*/Default/" + edgeProfilePath = homeDir + "/.config/microsoft-edge/Default/" braveProfilePath = homeDir + "/.config/BraveSoftware/Brave-Browser/Default/" chromeBetaProfilePath = homeDir + "/.config/google-chrome-beta/Default/" operaProfilePath = homeDir + "/.config/opera/Default/" diff --git a/internal/item/sql.go b/internal/item/sql.go deleted file mode 100644 index eb11d32..0000000 --- a/internal/item/sql.go +++ /dev/null @@ -1 +0,0 @@ -package item diff --git a/internal/log/log.go b/internal/log/log.go index d6a8688..09b302d 100644 --- a/internal/log/log.go +++ b/internal/log/log.go @@ -17,7 +17,7 @@ func Init(l string) { } } -const template = "[{{datetime}}] [{{level}}] [{{caller}}] {{message}} {{data}} {{extra}}\n" +const template = "hack-browser-data [{{level}}] [{{caller}}] {{message}} {{data}} {{extra}}\n" // NewStdLogger instance func newStdLogger(level slog.Level) *slog.SugaredLogger { diff --git a/internal/utils/fileutil/filetutil.go b/internal/utils/fileutil/filetutil.go index f91948a..6b7bf60 100644 --- a/internal/utils/fileutil/filetutil.go +++ b/internal/utils/fileutil/filetutil.go @@ -45,11 +45,11 @@ func ReadFile(filename string) (string, error) { // CopyItemToLocal copies the file from the provided path to the local path func CopyItemToLocal(itemPaths map[item.Item]string) error { - for i, path := range itemPaths { + for i, p := range itemPaths { // var dstFilename = item.TempName() var filename = i.String() // TODO: Handle read file error - d, err := ioutil.ReadFile(path) + d, err := ioutil.ReadFile(p) if err != nil { fmt.Println(err.Error()) } @@ -113,7 +113,3 @@ func CompressDir(dir string) error { log.Debugf("Compress success, zip filename is %s", filename) return nil } - -// func CleanProfilePath(p string) string { -// -// } diff --git a/internal/utils/typeutil/typeutil.go b/internal/utils/typeutil/typeutil.go index 2402bb6..986585b 100644 --- a/internal/utils/typeutil/typeutil.go +++ b/internal/utils/typeutil/typeutil.go @@ -1,5 +1,11 @@ package typeutil +import ( + "time" + + "golang.org/x/exp/constraints" +) + // Keys returns a slice of the keys of the map. based with go 1.18 generics func Keys[K comparable, V any](m map[K]V) []K { r := make([]K, 0, len(m)) @@ -8,3 +14,32 @@ func Keys[K comparable, V any](m map[K]V) []K { } return r } + +func IntToBool[T constraints.Signed](a T) bool { + switch a { + case 0, -1: + return false + } + return true +} + +func TimeStamp(stamp int64) time.Time { + s := time.Unix(stamp, 0) + if s.Local().Year() > 9999 { + return time.Date(9999, 12, 13, 23, 59, 59, 0, time.Local) + } + return s +} + +func TimeEpoch(epoch int64) time.Time { + maxTime := int64(99633311740000000) + if epoch > maxTime { + return time.Date(2049, 1, 1, 1, 1, 1, 1, time.Local) + } + t := time.Date(1601, 1, 1, 0, 0, 0, 0, time.Local) + d := time.Duration(epoch) + for i := 0; i < 1000; i++ { + t = t.Add(d) + } + return t +} diff --git a/internal/utils/utils.go b/internal/utils/utils.go deleted file mode 100644 index 19b5907..0000000 --- a/internal/utils/utils.go +++ /dev/null @@ -1,69 +0,0 @@ -package utils - -import ( - "fmt" - "io/ioutil" - "os" - "path" - "strings" - "time" -) - -func IntToBool(a int) bool { - switch a { - case 0, -1: - return false - } - return true -} - -func BookmarkType(a int64) string { - switch a { - case 1: - return "url" - default: - return "folder" - } -} - -func TimeStampFormat(stamp int64) time.Time { - s1 := time.Unix(stamp, 0) - if s1.Local().Year() > 9999 { - return time.Date(9999, 12, 13, 23, 59, 59, 0, time.Local) - } - return s1 -} - -func TimeEpochFormat(epoch int64) time.Time { - maxTime := int64(99633311740000000) - if epoch > maxTime { - return time.Date(2049, 1, 1, 1, 1, 1, 1, time.Local) - } - t := time.Date(1601, 1, 1, 0, 0, 0, 0, time.UTC) - d := time.Duration(epoch) - for i := 0; i < 1000; i++ { - t = t.Add(d) - } - return t -} - -func WriteFile(filename string, data []byte) error { - err := ioutil.WriteFile(filename, data, 0644) - if err != nil { - return nil - } - return err -} - -func FormatFilename(dir, browser, filename, format string) string { - r := strings.Replace(strings.TrimSpace(strings.ToLower(browser)), " ", "_", -1) - p := path.Join(dir, fmt.Sprintf("%s_%s.%s", r, filename, format)) - return p -} - -func MakeDir(dirName string) error { - if _, err := os.Stat(dirName); os.IsNotExist(err) { - return os.Mkdir(dirName, 0700) - } - return nil -}