@droponair/sdk-js 0.33.0 → 0.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.md +2 -0
- package/dist/attachment/attachment-client.js +4 -0
- package/dist/attachment/attachment-types.d.ts +11 -0
- package/dist/core/messaging-client.js +19 -0
- package/dist/core/types.d.ts +6 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.34.0
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **Files in group messages.** `sendGroupMessage(groupId, text, memberUserIds, { attachments })`
|
|
8
|
+
now carries attachment references, and a received `DecryptedGroupMessage` carries
|
|
9
|
+
`attachments`. Each member is handed the pointer and only the file keys wrapped for
|
|
10
|
+
their own devices. A file sent while a member was away arrives with the message when
|
|
11
|
+
they catch up, which previously carried nothing.
|
|
12
|
+
- **A lifetime per file.** `retentionSeconds` on an upload session asks for one file to
|
|
13
|
+
live a set time. Never longer than the app's own retention.
|
|
14
|
+
- **`deleteWhenEveryoneHasIt`.** The platform deletes the stored bytes as soon as every
|
|
15
|
+
recipient has fetched them, and answers a later request with "no longer available"
|
|
16
|
+
rather than a broken link.
|
|
17
|
+
|
|
3
18
|
## 0.33.0
|
|
4
19
|
|
|
5
20
|
### Added
|
package/README.md
CHANGED
|
@@ -346,6 +346,8 @@ client.onMessage(async (msg) => {
|
|
|
346
346
|
| `prepareAttachmentAndUpload(bytes, options)` | `Promise<AttachmentRef>` | Encrypt (E2EE), upload, finalize, return ref |
|
|
347
347
|
| `createUploadSession(options)` | `Promise<UploadSession>` | Low-level: presigned PUT URL only |
|
|
348
348
|
| `finalizeAttachment(attachmentId, sha256)` | `Promise<void>` | Low-level: commit integrity hash |
|
|
349
|
+
| `retentionSeconds` (upload option) | | How long this one file should live. Never granted longer than your own retention. |
|
|
350
|
+
| `deleteWhenEveryoneHasIt` (upload option) | | Delete the stored bytes as soon as every recipient has fetched them. A later request is answered "no longer available". |
|
|
349
351
|
| `downloadAttachment(ref)` | `Promise<DownloadedAttachment>` | Get presigned URL + download + decrypt |
|
|
350
352
|
| `revokeAttachment(attachmentId \| ref)` | `Promise<void>` | Revoke an attachment you sent; recipients get `ATTACHMENT_REVOKED` |
|
|
351
353
|
| `sendMessage(toUserId, text, { attachments })` | `Promise<{ messageId }>` | Send with attachments |
|
|
@@ -46,6 +46,10 @@ class AttachmentClient {
|
|
|
46
46
|
conversationId: opts.conversationId ?? '',
|
|
47
47
|
recipientUserIds: opts.recipientUserIds ?? [],
|
|
48
48
|
};
|
|
49
|
+
if (opts.retentionSeconds !== undefined)
|
|
50
|
+
body.retentionSeconds = opts.retentionSeconds;
|
|
51
|
+
if (opts.deleteWhenEveryoneHasIt)
|
|
52
|
+
body.deleteWhenEveryoneHasIt = true;
|
|
49
53
|
const resp = await this.deps.fetchFn(`${this.deps.httpUrl}/v1/attachments/upload-session`, {
|
|
50
54
|
method: 'POST',
|
|
51
55
|
headers: { Authorization: `Bearer ${jwt}`, 'Content-Type': 'application/json' },
|
|
@@ -44,6 +44,17 @@ export interface CreateUploadSessionOptions {
|
|
|
44
44
|
conversationId?: string;
|
|
45
45
|
/** Recipient user IDs (used by the server for download authorization). */
|
|
46
46
|
recipientUserIds?: string[];
|
|
47
|
+
/**
|
|
48
|
+
* How long this one file should live, in seconds. Optional, and never granted
|
|
49
|
+
* longer than the app's own retention. An app that works out a window per file
|
|
50
|
+
* sets it here instead of living with one number for everything.
|
|
51
|
+
*/
|
|
52
|
+
retentionSeconds?: number;
|
|
53
|
+
/**
|
|
54
|
+
* Delete the stored bytes as soon as every recipient has fetched them. The
|
|
55
|
+
* file then exists only on the devices it was sent to.
|
|
56
|
+
*/
|
|
57
|
+
deleteWhenEveryoneHasIt?: boolean;
|
|
47
58
|
}
|
|
48
59
|
/** Result of reserving an upload session. */
|
|
49
60
|
export interface UploadSession {
|
|
@@ -1863,6 +1863,7 @@ class MessagingClient {
|
|
|
1863
1863
|
fromUserId: notif.fromUserId,
|
|
1864
1864
|
timestamp: notif.timestamp,
|
|
1865
1865
|
plaintext,
|
|
1866
|
+
attachments: (notif.attachments ?? []).map(a => attachment_client_1.AttachmentClient.fromWire(a)),
|
|
1866
1867
|
};
|
|
1867
1868
|
for (const listener of this.groupMessageListeners) {
|
|
1868
1869
|
listener(msg);
|
|
@@ -2643,6 +2644,24 @@ class MessagingClient {
|
|
|
2643
2644
|
encryptedPayload: (0, bytes_1.fromBase64)(dp.encryptedPayloadBase64),
|
|
2644
2645
|
senderPublicKey: (0, bytes_1.fromBase64)(dp.senderPublicKeyBase64),
|
|
2645
2646
|
})),
|
|
2647
|
+
// Files travel with a late message too. Without this, somebody who was
|
|
2648
|
+
// away came back to a message that mentioned nothing at all: the live
|
|
2649
|
+
// path carried the pointer and the catch-up did not.
|
|
2650
|
+
attachments: (offline.attachments ?? []).map(a => ({
|
|
2651
|
+
attachmentId: a.attachmentId,
|
|
2652
|
+
storageHint: a.storageHint ?? '',
|
|
2653
|
+
mimeType: a.mimeType ?? '',
|
|
2654
|
+
sizeBytes: a.sizeBytes ?? 0,
|
|
2655
|
+
sha256: a.sha256 ?? '',
|
|
2656
|
+
encryptionType: a.encryptionType === 'CLEARTEXT' ? 1 : 0,
|
|
2657
|
+
thumbnailAttachmentId: a.thumbnailAttachmentId ?? '',
|
|
2658
|
+
wrappedKeys: (a.wrappedKeys ?? []).map(k => ({
|
|
2659
|
+
deviceId: k.deviceId,
|
|
2660
|
+
wrappedKey: (0, bytes_1.fromBase64)(k.wrappedKeyBase64 ?? ''),
|
|
2661
|
+
senderPublicKey: (0, bytes_1.fromBase64)(k.senderPublicKeyBase64 ?? ''),
|
|
2662
|
+
nonce: (0, bytes_1.fromBase64)(k.nonceBase64 ?? ''),
|
|
2663
|
+
})),
|
|
2664
|
+
})),
|
|
2646
2665
|
};
|
|
2647
2666
|
// The same path a live message takes, so decryption, de-duplication and
|
|
2648
2667
|
// the callback behave identically.
|
package/dist/core/types.d.ts
CHANGED
|
@@ -222,6 +222,12 @@ export interface DecryptedGroupMessage {
|
|
|
222
222
|
fromUserId: string;
|
|
223
223
|
timestamp: number;
|
|
224
224
|
plaintext: string;
|
|
225
|
+
/**
|
|
226
|
+
* Files this message points at, if any. The bytes are fetched separately with
|
|
227
|
+
* `downloadAttachment`; what arrives here is the pointer and the file key
|
|
228
|
+
* wrapped for this device.
|
|
229
|
+
*/
|
|
230
|
+
attachments?: import('../attachment/attachment-types').AttachmentRef[];
|
|
225
231
|
}
|
|
226
232
|
export type GroupMessageCallback = (message: DecryptedGroupMessage) => void;
|
|
227
233
|
export type GroupCallEventType = 'GROUP_CALL_INVITE' | 'GROUP_CALL_RINGING' | 'GROUP_CALL_JOIN' | 'GROUP_CALL_LEAVE' | 'GROUP_CALL_END' | 'GROUP_CALL_ENDED' | 'GROUP_CALL_PARTICIPANT_JOINED' | 'GROUP_CALL_PARTICIPANT_LEFT' | 'GROUP_CALL_PARTICIPANT_REMOVED' | 'GROUP_CALL_ALREADY_ACTIVE' | 'GROUP_CALL_SDP_OFFER' | 'GROUP_CALL_SDP_ANSWER' | 'GROUP_CALL_ICE_CANDIDATE' | 'GROUP_CALL_SCREEN_SHARE_STARTED' | 'GROUP_CALL_SCREEN_SHARE_STOPPED' | 'GROUP_CALL_HOST_TRANSFER' | 'GROUP_CALL_COHOST_APPOINT' | 'GROUP_CALL_COHOST_REVOKE' | 'GROUP_CALL_ROLE_CHANGED' | 'GROUP_CALL_MUTE_PARTICIPANT' | 'GROUP_CALL_REMOVE_PARTICIPANT' | 'GROUP_CALL_WAITING_ROOM_REQUEST' | 'GROUP_CALL_WAITING_ROOM_JOINED' | 'GROUP_CALL_WAITING_ROOM_ADMIT' | 'GROUP_CALL_WAITING_ROOM_ADMITTED' | 'GROUP_CALL_WAITING_ROOM_REJECT' | 'GROUP_CALL_WAITING_ROOM_REJECTED' | 'GROUP_CALL_JOINED' | 'GROUP_CALL_WAITING_ROOM_PENDING' | 'GROUP_CALL_HOST_REQUIRED' | 'GROUP_CALL_ROOM_CLOSED' | 'GROUP_CALL_STAGE_HAND_RAISED' | 'GROUP_CALL_STAGE_HAND_LOWERED' | 'GROUP_CALL_STAGE_PROMOTE' | 'GROUP_CALL_STAGE_DEMOTE' | 'GROUP_CALL_STAGE_QUESTION' | 'GROUP_CALL_RECORDING_STARTED' | 'GROUP_CALL_RECORDING_STOPPED' | 'GROUP_CALL_RECORDING_AVAILABLE';
|
package/dist/version.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* MINOR, additive feature (e.g. multi-device payloads, new call event type)
|
|
8
8
|
* PATCH, bug-fix / perf improvement with no wire or API change
|
|
9
9
|
*/
|
|
10
|
-
export declare const SDK_VERSION = "0.
|
|
10
|
+
export declare const SDK_VERSION = "0.34.0";
|
|
11
11
|
/**
|
|
12
12
|
* Binary encrypted-payload format version.
|
|
13
13
|
* Included as the first byte of every encrypted payload so receivers can
|
package/dist/version.js
CHANGED
|
@@ -10,7 +10,7 @@ exports.PROTOCOL_VERSION = exports.PAYLOAD_FORMAT_VERSION = exports.SDK_VERSION
|
|
|
10
10
|
* MINOR, additive feature (e.g. multi-device payloads, new call event type)
|
|
11
11
|
* PATCH, bug-fix / perf improvement with no wire or API change
|
|
12
12
|
*/
|
|
13
|
-
exports.SDK_VERSION = '0.
|
|
13
|
+
exports.SDK_VERSION = '0.34.0';
|
|
14
14
|
/**
|
|
15
15
|
* Binary encrypted-payload format version.
|
|
16
16
|
* Included as the first byte of every encrypted payload so receivers can
|
package/package.json
CHANGED