]> nmode's Git Repositories - signal-cli/blob - lib/src/main/java/org/asamk/signal/manager/api/RecipientIdentifier.java
Add support for using PNI as recipient
[signal-cli] / lib / src / main / java / org / asamk / signal / manager / api / RecipientIdentifier.java
1 package org.asamk.signal.manager.api;
2
3 import org.slf4j.Logger;
4 import org.slf4j.LoggerFactory;
5 import org.whispersystems.signalservice.api.util.PhoneNumberFormatter;
6 import org.whispersystems.signalservice.api.util.UuidUtil;
7
8 import java.util.UUID;
9
10 public sealed interface RecipientIdentifier {
11
12 String getIdentifier();
13
14 record NoteToSelf() implements RecipientIdentifier {
15
16 public static final NoteToSelf INSTANCE = new NoteToSelf();
17
18 @Override
19 public String getIdentifier() {
20 return "Note-To-Self";
21 }
22 }
23
24 sealed interface Single extends RecipientIdentifier {
25
26 static Single fromString(String identifier, String localNumber) throws InvalidNumberException {
27 try {
28 if (UuidUtil.isUuid(identifier)) {
29 return new Uuid(UUID.fromString(identifier));
30 }
31
32 if (identifier.startsWith("PNI:")) {
33 final var pni = identifier.substring(4);
34 if (!UuidUtil.isUuid(pni)) {
35 throw new InvalidNumberException("Invalid PNI");
36 }
37 return new Pni(UUID.fromString(pni));
38 }
39
40 if (identifier.startsWith("u:")) {
41 return new Username(identifier.substring(2));
42 }
43
44 final var normalizedNumber = PhoneNumberFormatter.formatNumber(identifier, localNumber);
45 if (!normalizedNumber.equals(identifier)) {
46 final Logger logger = LoggerFactory.getLogger(RecipientIdentifier.class);
47 logger.debug("Normalized number {} to {}.", identifier, normalizedNumber);
48 }
49 return new Number(normalizedNumber);
50 } catch (org.whispersystems.signalservice.api.util.InvalidNumberException e) {
51 throw new InvalidNumberException(e.getMessage(), e);
52 }
53 }
54
55 static Single fromAddress(RecipientAddress address) {
56 if (address.number().isPresent()) {
57 return new Number(address.number().get());
58 } else if (address.aci().isPresent()) {
59 return new Uuid(UUID.fromString(address.aci().get()));
60 } else if (address.pni().isPresent()) {
61 return new Pni(UUID.fromString(address.pni().get().substring(4)));
62 } else if (address.username().isPresent()) {
63 return new Username(address.username().get());
64 }
65 throw new AssertionError("RecipientAddress without identifier");
66 }
67
68 RecipientAddress toPartialRecipientAddress();
69 }
70
71 record Uuid(UUID uuid) implements Single {
72
73 @Override
74 public String getIdentifier() {
75 return uuid.toString();
76 }
77
78 @Override
79 public RecipientAddress toPartialRecipientAddress() {
80 return new RecipientAddress(uuid);
81 }
82 }
83
84 record Pni(UUID pni) implements Single {
85
86 @Override
87 public String getIdentifier() {
88 return "PNI:" + pni.toString();
89 }
90
91 @Override
92 public RecipientAddress toPartialRecipientAddress() {
93 return new RecipientAddress(null, getIdentifier(), null, null);
94 }
95 }
96
97 record Number(String number) implements Single {
98
99 @Override
100 public String getIdentifier() {
101 return number;
102 }
103
104 @Override
105 public RecipientAddress toPartialRecipientAddress() {
106 return new RecipientAddress(number);
107 }
108 }
109
110 record Username(String username) implements Single {
111
112 @Override
113 public String getIdentifier() {
114 return "u:" + username;
115 }
116
117 @Override
118 public RecipientAddress toPartialRecipientAddress() {
119 return new RecipientAddress(null, null, null, username);
120 }
121 }
122
123 record Group(GroupId groupId) implements RecipientIdentifier {
124
125 @Override
126 public String getIdentifier() {
127 return groupId.toBase64();
128 }
129 }
130 }