1 /*
2  * // Copyright 2021 signald contributors
3  * // SPDX-License-Identifier: GPL-3.0-only
4  * // See included LICENSE file
5  */
6 
7 package io.finn.signald;
8 
9 import io.finn.signald.db.AccountDataTable;
10 import io.finn.signald.db.AccountsTable;
11 import io.finn.signald.db.DatabaseProtocolStore;
12 import io.finn.signald.db.RecipientsTable;
13 import io.finn.signald.exceptions.InvalidProxyException;
14 import io.finn.signald.exceptions.NoSuchAccountException;
15 import io.finn.signald.exceptions.ServerNotFoundException;
16 import java.io.IOException;
17 import java.sql.SQLException;
18 import java.util.UUID;
19 import org.apache.logging.log4j.LogManager;
20 import org.apache.logging.log4j.Logger;
21 import org.whispersystems.libsignal.IdentityKeyPair;
22 import org.whispersystems.signalservice.api.push.SignalServiceAddress;
23 import org.whispersystems.signalservice.internal.util.DynamicCredentialsProvider;
24 
25 public class Account {
26   private static final Logger logger = LogManager.getLogger();
27   private final UUID accountUUID;
28 
Account(UUID accountUUID)29   public Account(UUID accountUUID) { this.accountUUID = accountUUID; }
30 
getE164()31   public String getE164() throws SQLException, NoSuchAccountException { return AccountsTable.getE164(accountUUID); }
32 
getUUID()33   public UUID getUUID() { return accountUUID; }
34 
getRecipients()35   public RecipientsTable getRecipients() { return new RecipientsTable(accountUUID); }
36 
getSignalDependencies()37   public SignalDependencies getSignalDependencies() throws SQLException, ServerNotFoundException, IOException, InvalidProxyException, NoSuchAccountException {
38     return SignalDependencies.get(accountUUID);
39   }
40 
getProtocolStore()41   public DatabaseProtocolStore getProtocolStore() { return new DatabaseProtocolStore(accountUUID); }
42 
getCredentialsProvider()43   public DynamicCredentialsProvider getCredentialsProvider() throws SQLException, NoSuchAccountException {
44     return new DynamicCredentialsProvider(accountUUID, getE164(), getPassword(), getDeviceId());
45   }
46 
getLocalRegistrationId()47   public int getLocalRegistrationId() throws SQLException { return AccountDataTable.getInt(accountUUID, AccountDataTable.Key.LOCAL_REGISTRATION_ID); }
48 
setLocalRegistrationId(int localRegistrationId)49   public void setLocalRegistrationId(int localRegistrationId) throws SQLException {
50     AccountDataTable.set(accountUUID, AccountDataTable.Key.LOCAL_REGISTRATION_ID, localRegistrationId);
51   }
52 
getDeviceId()53   public int getDeviceId() throws SQLException { return AccountDataTable.getInt(accountUUID, AccountDataTable.Key.DEVICE_ID); }
54 
setDeviceId(int deviceId)55   public void setDeviceId(int deviceId) throws SQLException { AccountDataTable.set(accountUUID, AccountDataTable.Key.DEVICE_ID, deviceId); }
56 
getMultiDevice()57   public boolean getMultiDevice() {
58     try {
59       Boolean isMultidevice = AccountDataTable.getBoolean(accountUUID, AccountDataTable.Key.MULTI_DEVICE);
60       if (isMultidevice == null) {
61         isMultidevice = getDeviceId() != SignalServiceAddress.DEFAULT_DEVICE_ID;
62         AccountDataTable.set(accountUUID, AccountDataTable.Key.MULTI_DEVICE, isMultidevice);
63         return false;
64       }
65       return isMultidevice;
66     } catch (SQLException e) {
67       logger.error("error fetching mutlidevice status from db", e);
68       return false;
69     }
70   }
71 
setMultiDevice(boolean multidevice)72   public void setMultiDevice(boolean multidevice) throws SQLException { AccountDataTable.set(accountUUID, AccountDataTable.Key.MULTI_DEVICE, multidevice); }
73 
getPassword()74   public String getPassword() throws SQLException { return AccountDataTable.getString(accountUUID, AccountDataTable.Key.PASSWORD); }
75 
setPassword(String password)76   public void setPassword(String password) throws SQLException { AccountDataTable.set(accountUUID, AccountDataTable.Key.PASSWORD, password); }
77 
getIdentityKeyPair()78   public IdentityKeyPair getIdentityKeyPair() throws SQLException {
79     byte[] serialized = AccountDataTable.getBytes(accountUUID, AccountDataTable.Key.OWN_IDENTITY_KEY_PAIR);
80     if (serialized == null) {
81       return null;
82     }
83     return new IdentityKeyPair(serialized);
84   }
85 
setIdentityKeyPair(IdentityKeyPair identityKeyPair)86   public void setIdentityKeyPair(IdentityKeyPair identityKeyPair) throws SQLException {
87     AccountDataTable.set(accountUUID, AccountDataTable.Key.OWN_IDENTITY_KEY_PAIR, identityKeyPair.serialize());
88   }
89 
getLastPreKeyRefresh()90   public long getLastPreKeyRefresh() throws SQLException { return AccountDataTable.getLong(accountUUID, AccountDataTable.Key.LAST_PRE_KEY_REFRESH); }
91 
setLastPreKeyRefreshNow()92   public void setLastPreKeyRefreshNow() throws SQLException { AccountDataTable.set(accountUUID, AccountDataTable.Key.LAST_PRE_KEY_REFRESH, System.currentTimeMillis()); }
93 
setLastPreKeyRefresh(long timestamp)94   public void setLastPreKeyRefresh(long timestamp) throws SQLException { AccountDataTable.set(accountUUID, AccountDataTable.Key.LAST_PRE_KEY_REFRESH, timestamp); }
95 
getDeviceName()96   public String getDeviceName() throws SQLException { return AccountDataTable.getString(accountUUID, AccountDataTable.Key.DEVICE_NAME); }
97 
setDeviceName(String deviceName)98   public void setDeviceName(String deviceName) throws SQLException { AccountDataTable.set(accountUUID, AccountDataTable.Key.DEVICE_NAME, deviceName); }
99 
getLastAccountRefresh()100   public int getLastAccountRefresh() throws SQLException { return AccountDataTable.getInt(accountUUID, AccountDataTable.Key.LAST_ACCOUNT_REFRESH); }
101 
setLastAccountRefresh(int accountRefreshVersion)102   public void setLastAccountRefresh(int accountRefreshVersion) throws SQLException {
103     AccountDataTable.set(accountUUID, AccountDataTable.Key.LAST_ACCOUNT_REFRESH, accountRefreshVersion);
104   }
105 
getSenderCertificate()106   public byte[] getSenderCertificate() throws SQLException { return AccountDataTable.getBytes(accountUUID, AccountDataTable.Key.SENDER_CERTIFICATE); }
107 
setSenderCertificate(byte[] senderCertificate)108   public void setSenderCertificate(byte[] senderCertificate) throws SQLException { AccountDataTable.set(accountUUID, AccountDataTable.Key.SENDER_CERTIFICATE, senderCertificate); }
109 
getLastSenderCertificateRefreshTime()110   public long getLastSenderCertificateRefreshTime() throws SQLException { return AccountDataTable.getLong(accountUUID, AccountDataTable.Key.SENDER_CERTIFICATE_REFRESH_TIME); }
111 
setSenderCertificateRefreshTimeNow()112   public void setSenderCertificateRefreshTimeNow() throws SQLException {
113     AccountDataTable.set(accountUUID, AccountDataTable.Key.SENDER_CERTIFICATE_REFRESH_TIME, System.currentTimeMillis());
114   }
115 
getPreKeyIdOffset()116   public int getPreKeyIdOffset() throws SQLException {
117     int offset = AccountDataTable.getInt(accountUUID, AccountDataTable.Key.PRE_KEY_ID_OFFSET);
118     if (offset == -1) {
119       return 0;
120     }
121     return offset;
122   }
123 
setPreKeyIdOffset(int preKeyIdOffset)124   public void setPreKeyIdOffset(int preKeyIdOffset) throws SQLException { AccountDataTable.set(accountUUID, AccountDataTable.Key.PRE_KEY_ID_OFFSET, preKeyIdOffset); }
125 
getNextSignedPreKeyId()126   public int getNextSignedPreKeyId() throws SQLException {
127     int id = AccountDataTable.getInt(accountUUID, AccountDataTable.Key.NEXT_SIGNED_PRE_KEY_ID);
128     if (id == -1) {
129       return 0;
130     }
131     return id;
132   }
133 
setNextSignedPreKeyId(int nextSignedPreKeyId)134   public void setNextSignedPreKeyId(int nextSignedPreKeyId) throws SQLException {
135     AccountDataTable.set(accountUUID, AccountDataTable.Key.NEXT_SIGNED_PRE_KEY_ID, nextSignedPreKeyId);
136   }
137 }
138