969600b6ee
- assets/icons/ 共 80+ 张真实品牌图标嵌入 UI 包 - entry 新增 IconKey 字段,持久化到 config.Entry.IconName - iconPickerDialog 网格布局图标选择器 - Add 完成后自动弹出图标选择器,Skip 则用 vendor 占位图 - ⋯ 菜单新增 "Change icon..." 项 - vendorIconFor 解析顺序:catalog → vendor 占位 → qr 兜底
51 lines
1.6 KiB
Go
51 lines
1.6 KiB
Go
package ui
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"git.wxccs.org/iceking2nd/winauth-go/internal/authenticator"
|
|
"git.wxccs.org/iceking2nd/winauth-go/internal/config"
|
|
)
|
|
|
|
// entryFromAuthenticator builds a serializable config.Entry from an
|
|
// in-memory authenticator plus its display name. The vendor string is
|
|
// derived from the authenticator's Name() (which already returns
|
|
// "google" / "microsoft" / "okta" / "hotp" / "battlenet" / "steam").
|
|
func entryFromAuthenticator(name string, a authenticator.Authenticator, hotkey, iconKey string) config.Entry {
|
|
return config.Entry{
|
|
Name: name,
|
|
Vendor: a.Name(),
|
|
IconName: iconKey,
|
|
SecretRaw: a.SecretData(),
|
|
Hotkey: hotkey,
|
|
}
|
|
}
|
|
|
|
// buildAuthenticator is the reverse of entryFromAuthenticator: it picks
|
|
// the right concrete type based on vendor, then asks it to parse the
|
|
// stored secret blob.
|
|
func buildAuthenticator(e config.Entry) (authenticator.Authenticator, error) {
|
|
const fn = "internal.ui.buildAuthenticator"
|
|
var a authenticator.Authenticator
|
|
switch e.Vendor {
|
|
case "google", "":
|
|
a = authenticator.NewGoogleAuthenticator()
|
|
case "microsoft":
|
|
a = authenticator.NewMicrosoftAuthenticator()
|
|
case "okta":
|
|
a = authenticator.NewOktaVerifyAuthenticator()
|
|
case "hotp":
|
|
a = authenticator.NewHOTPAuthenticator()
|
|
case "battlenet":
|
|
a = authenticator.NewBattleNetAuthenticator()
|
|
case "steam":
|
|
a = authenticator.NewSteamAuthenticator()
|
|
default:
|
|
return nil, fmt.Errorf("%s: unknown vendor %q", fn, e.Vendor)
|
|
}
|
|
if err := a.SetSecretData(e.SecretRaw); err != nil {
|
|
return nil, fmt.Errorf("%s: decode entry %q: %w", fn, e.Name, err)
|
|
}
|
|
return a, nil
|
|
}
|