|
@@ -38,11 +38,13 @@ const (
|
38
|
38
|
keyAccountVHost = "account.vhost %s"
|
39
|
39
|
keyCertToAccount = "account.creds.certfp %s"
|
40
|
40
|
keyAccountChannels = "account.channels %s" // channels registered to the account
|
41
|
|
- keyAccountJoinedChannels = "account.joinedto %s" // channels a persistent client has joined
|
42
|
41
|
keyAccountLastSeen = "account.lastseen %s"
|
43
|
42
|
keyAccountModes = "account.modes %s" // user modes for the always-on client as a string
|
44
|
43
|
keyAccountRealname = "account.realname %s" // client realname stored as string
|
45
|
44
|
keyAccountSuspended = "account.suspended %s" // client realname stored as string
|
|
45
|
+ // for an always-on client, a map of channel names they're in to their current modes
|
|
46
|
+ // (not to be confused with their amodes, which a non-always-on client can have):
|
|
47
|
+ keyAccountChannelToModes = "account.channeltomodes %s"
|
46
|
48
|
|
47
|
49
|
maxCertfpsPerAccount = 5
|
48
|
50
|
)
|
|
@@ -542,24 +544,34 @@ func (am *AccountManager) setPassword(account string, password string, hasPrivs
|
542
|
544
|
return err
|
543
|
545
|
}
|
544
|
546
|
|
545
|
|
-func (am *AccountManager) saveChannels(account string, channels []string) {
|
546
|
|
- channelsStr := strings.Join(channels, ",")
|
547
|
|
- key := fmt.Sprintf(keyAccountJoinedChannels, account)
|
|
547
|
+func (am *AccountManager) saveChannels(account string, channelToModes map[string]string) {
|
|
548
|
+ j, err := json.Marshal(channelToModes)
|
|
549
|
+ if err != nil {
|
|
550
|
+ am.server.logger.Error("internal", "couldn't marshal channel-to-modes", account, err.Error())
|
|
551
|
+ return
|
|
552
|
+ }
|
|
553
|
+ jStr := string(j)
|
|
554
|
+ key := fmt.Sprintf(keyAccountChannelToModes, account)
|
548
|
555
|
am.server.store.Update(func(tx *buntdb.Tx) error {
|
549
|
|
- tx.Set(key, channelsStr, nil)
|
|
556
|
+ tx.Set(key, jStr, nil)
|
550
|
557
|
return nil
|
551
|
558
|
})
|
552
|
559
|
}
|
553
|
560
|
|
554
|
|
-func (am *AccountManager) loadChannels(account string) (channels []string) {
|
555
|
|
- key := fmt.Sprintf(keyAccountJoinedChannels, account)
|
|
561
|
+func (am *AccountManager) loadChannels(account string) (channelToModes map[string]string) {
|
|
562
|
+ key := fmt.Sprintf(keyAccountChannelToModes, account)
|
556
|
563
|
var channelsStr string
|
557
|
564
|
am.server.store.View(func(tx *buntdb.Tx) error {
|
558
|
565
|
channelsStr, _ = tx.Get(key)
|
559
|
566
|
return nil
|
560
|
567
|
})
|
561
|
|
- if channelsStr != "" {
|
562
|
|
- return strings.Split(channelsStr, ",")
|
|
568
|
+ if channelsStr == "" {
|
|
569
|
+ return nil
|
|
570
|
+ }
|
|
571
|
+ err := json.Unmarshal([]byte(channelsStr), &channelToModes)
|
|
572
|
+ if err != nil {
|
|
573
|
+ am.server.logger.Error("internal", "couldn't marshal channel-to-modes", account, err.Error())
|
|
574
|
+ return nil
|
563
|
575
|
}
|
564
|
576
|
return
|
565
|
577
|
}
|
|
@@ -1454,7 +1466,7 @@ func (am *AccountManager) Unregister(account string, erase bool) error {
|
1454
|
1466
|
settingsKey := fmt.Sprintf(keyAccountSettings, casefoldedAccount)
|
1455
|
1467
|
vhostKey := fmt.Sprintf(keyAccountVHost, casefoldedAccount)
|
1456
|
1468
|
channelsKey := fmt.Sprintf(keyAccountChannels, casefoldedAccount)
|
1457
|
|
- joinedChannelsKey := fmt.Sprintf(keyAccountJoinedChannels, casefoldedAccount)
|
|
1469
|
+ joinedChannelsKey := fmt.Sprintf(keyAccountChannelToModes, casefoldedAccount)
|
1458
|
1470
|
lastSeenKey := fmt.Sprintf(keyAccountLastSeen, casefoldedAccount)
|
1459
|
1471
|
unregisteredKey := fmt.Sprintf(keyAccountUnregistered, casefoldedAccount)
|
1460
|
1472
|
modesKey := fmt.Sprintf(keyAccountModes, casefoldedAccount)
|