@@ -9,14 +9,35 @@ type AccountInfoOutput struct {
99 Account Account
1010}
1111
12+ type AccountsInfoOutput struct {
13+ Accounts []Account
14+ Current string
15+ }
16+
17+ // Try read as Multiple Accounts storage
18+ // otherwise as single account
1219func (t * appstore ) AccountInfo () (AccountInfoOutput , error ) {
13- data , err := t .keychain .Get ("account" )
20+ data , err := t .keychain .Get (AccountKey )
1421 if err != nil {
1522 return AccountInfoOutput {}, fmt .Errorf ("failed to get account: %w" , err )
1623 }
1724
1825 var acc Account
26+ var accounts AccountStorage
27+
28+ err = json .Unmarshal (data , & accounts )
29+ if err == nil && len (accounts .Accounts ) > 0 {
30+ // Return current account
31+ for _ , a := range accounts .Accounts {
32+ if a .Email == accounts .Current {
33+ return AccountInfoOutput {
34+ Account : a ,
35+ }, nil
36+ }
37+ }
38+ }
1939
40+ // Fallback to single account
2041 err = json .Unmarshal (data , & acc )
2142 if err != nil {
2243 return AccountInfoOutput {}, fmt .Errorf ("failed to unmarshal json: %w" , err )
@@ -26,3 +47,101 @@ func (t *appstore) AccountInfo() (AccountInfoOutput, error) {
2647 Account : acc ,
2748 }, nil
2849}
50+
51+ func (t * appstore ) AccountsInfo () (AccountsInfoOutput , error ) {
52+ data , err := t .keychain .Get (AccountKey )
53+ if err != nil {
54+ return AccountsInfoOutput {}, fmt .Errorf ("failed to get account storage: %w" , err )
55+ }
56+
57+ var storage AccountStorage
58+
59+ err = json .Unmarshal (data , & storage )
60+ if err != nil {
61+ return AccountsInfoOutput {}, fmt .Errorf ("failed to unmarshal json: %w" , err )
62+ }
63+
64+ return AccountsInfoOutput (storage ), nil
65+ }
66+
67+ // read from keychain and save to storage
68+ // if is v2 data, just save it
69+ // if is old data, convert and save it
70+ func (t * appstore ) saveAccount (acc Account ) (Account , error ) {
71+
72+ var accountStorage AccountStorage
73+ var accInKeychain Account
74+
75+ rootData , err := t .keychain .Get (AccountKey )
76+ if err != nil {
77+ // Ignore error if account does not exist yet
78+ return Account {}, err
79+ }
80+ err = json .Unmarshal (rootData , & accountStorage )
81+
82+ if err != nil {
83+ err = json .Unmarshal (rootData , & accInKeychain )
84+ if err == nil {
85+ accountStorage = AccountStorage {
86+ Accounts : []Account {accInKeychain },
87+ Current : accInKeychain .Email ,
88+ }
89+ }
90+ }
91+
92+ // handle deduplicate accounts
93+ var found bool
94+ for _ , a := range accountStorage .Accounts {
95+ if a .Email == acc .Email {
96+ found = true
97+ break
98+ }
99+ }
100+ if ! found {
101+ accountStorage .Accounts = append (accountStorage .Accounts , acc )
102+ }
103+ accountStorage .Current = acc .Email
104+
105+ rootData , err = json .Marshal (accountStorage )
106+ if err != nil {
107+ return Account {}, fmt .Errorf ("failed to marshal json: %w" , err )
108+ }
109+ err = t .keychain .Set (AccountKey , rootData )
110+ if err != nil {
111+ return Account {}, fmt .Errorf ("failed to save account storage in keychain: %w" , err )
112+ }
113+ return acc , nil
114+ }
115+
116+ func (t * appstore ) SwitchAccount (email string ) (Account , error ) {
117+ accountStorage , err := t .AccountsInfo ()
118+ if err != nil {
119+ return Account {}, fmt .Errorf ("failed to get accounts info: %w" , err )
120+ }
121+
122+ var found bool
123+ var res Account
124+ for _ , acc := range accountStorage .Accounts {
125+ if acc .Email == email {
126+ found = true
127+ res = acc
128+ break
129+ }
130+ }
131+ if ! found {
132+ return Account {}, fmt .Errorf ("account with email %s not found" , email )
133+ }
134+
135+ accountStorage .Current = email
136+
137+ rootData , err := json .Marshal (accountStorage )
138+ if err != nil {
139+ return Account {}, fmt .Errorf ("failed to marshal json: %w" , err )
140+ }
141+ err = t .keychain .Set (AccountKey , rootData )
142+ if err != nil {
143+ return Account {}, fmt .Errorf ("failed to save account storage in keychain: %w" , err )
144+ }
145+
146+ return res , nil
147+ }
0 commit comments