signal-sdk 0.0.9 → 0.1.1
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/README.md +184 -61
- package/dist/MultiAccountManager.d.ts +149 -0
- package/dist/MultiAccountManager.js +320 -0
- package/dist/SignalBot.d.ts +1 -0
- package/dist/SignalBot.js +20 -2
- package/dist/SignalCli.d.ts +315 -16
- package/dist/SignalCli.js +880 -26
- package/dist/__tests__/MultiAccountManager.test.d.ts +4 -0
- package/dist/__tests__/MultiAccountManager.test.js +209 -0
- package/dist/__tests__/SignalBot.additional.test.d.ts +5 -0
- package/dist/__tests__/SignalBot.additional.test.js +353 -0
- package/dist/__tests__/SignalBot.test.js +5 -0
- package/dist/__tests__/SignalCli.advanced.test.d.ts +5 -0
- package/dist/__tests__/SignalCli.advanced.test.js +295 -0
- package/dist/__tests__/SignalCli.e2e.test.d.ts +5 -0
- package/dist/__tests__/SignalCli.e2e.test.js +240 -0
- package/dist/__tests__/SignalCli.integration.test.d.ts +5 -0
- package/dist/__tests__/SignalCli.integration.test.js +225 -0
- package/dist/__tests__/SignalCli.methods.test.d.ts +5 -0
- package/dist/__tests__/SignalCli.methods.test.js +556 -0
- package/dist/__tests__/SignalCli.parsing.test.d.ts +5 -0
- package/dist/__tests__/SignalCli.parsing.test.js +258 -0
- package/dist/__tests__/SignalCli.test.js +249 -13
- package/dist/__tests__/config.test.d.ts +5 -0
- package/dist/__tests__/config.test.js +252 -0
- package/dist/__tests__/errors.test.d.ts +5 -0
- package/dist/__tests__/errors.test.js +276 -0
- package/dist/__tests__/retry.test.d.ts +4 -0
- package/dist/__tests__/retry.test.js +123 -0
- package/dist/__tests__/validators.test.d.ts +4 -0
- package/dist/__tests__/validators.test.js +147 -0
- package/dist/config.d.ts +82 -0
- package/dist/config.js +116 -0
- package/dist/errors.d.ts +32 -0
- package/dist/errors.js +75 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +7 -1
- package/dist/interfaces.d.ts +200 -10
- package/dist/interfaces.js +1 -1
- package/dist/retry.d.ts +56 -0
- package/dist/retry.js +152 -0
- package/dist/validators.d.ts +59 -0
- package/dist/validators.js +170 -0
- package/package.json +1 -1
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Input validation utilities for Signal SDK
|
|
4
|
+
* Provides strict validation for all inputs
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.validatePhoneNumber = validatePhoneNumber;
|
|
8
|
+
exports.validateGroupId = validateGroupId;
|
|
9
|
+
exports.validateRecipient = validateRecipient;
|
|
10
|
+
exports.validateMessage = validateMessage;
|
|
11
|
+
exports.validateAttachments = validateAttachments;
|
|
12
|
+
exports.validateTimestamp = validateTimestamp;
|
|
13
|
+
exports.validateEmoji = validateEmoji;
|
|
14
|
+
exports.validateDeviceId = validateDeviceId;
|
|
15
|
+
exports.sanitizeInput = sanitizeInput;
|
|
16
|
+
const errors_1 = require("./errors");
|
|
17
|
+
/**
|
|
18
|
+
* Validates a phone number format (E.164)
|
|
19
|
+
* @param phoneNumber Phone number to validate
|
|
20
|
+
* @throws ValidationError if invalid
|
|
21
|
+
*/
|
|
22
|
+
function validatePhoneNumber(phoneNumber) {
|
|
23
|
+
if (!phoneNumber) {
|
|
24
|
+
throw new errors_1.ValidationError('Phone number is required', 'phoneNumber');
|
|
25
|
+
}
|
|
26
|
+
if (typeof phoneNumber !== 'string') {
|
|
27
|
+
throw new errors_1.ValidationError('Phone number must be a string', 'phoneNumber');
|
|
28
|
+
}
|
|
29
|
+
// E.164 format: + followed by 1-15 digits
|
|
30
|
+
const e164Regex = /^\+[1-9]\d{1,14}$/;
|
|
31
|
+
if (!e164Regex.test(phoneNumber)) {
|
|
32
|
+
throw new errors_1.ValidationError('Phone number must be in E.164 format (e.g., +33123456789)', 'phoneNumber');
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Validates a group ID format
|
|
37
|
+
* @param groupId Group ID to validate
|
|
38
|
+
* @throws ValidationError if invalid
|
|
39
|
+
*/
|
|
40
|
+
function validateGroupId(groupId) {
|
|
41
|
+
if (!groupId) {
|
|
42
|
+
throw new errors_1.ValidationError('Group ID is required', 'groupId');
|
|
43
|
+
}
|
|
44
|
+
if (typeof groupId !== 'string') {
|
|
45
|
+
throw new errors_1.ValidationError('Group ID must be a string', 'groupId');
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Validates a recipient (phone number, UUID, or username)
|
|
50
|
+
* @param recipient Recipient to validate
|
|
51
|
+
* @throws ValidationError if invalid
|
|
52
|
+
*/
|
|
53
|
+
function validateRecipient(recipient) {
|
|
54
|
+
if (!recipient) {
|
|
55
|
+
throw new errors_1.ValidationError('Recipient is required', 'recipient');
|
|
56
|
+
}
|
|
57
|
+
if (typeof recipient !== 'string') {
|
|
58
|
+
throw new errors_1.ValidationError('Recipient must be a string', 'recipient');
|
|
59
|
+
}
|
|
60
|
+
// Check if it's a username (starts with u:)
|
|
61
|
+
if (recipient.startsWith('u:')) {
|
|
62
|
+
if (recipient.length < 3) {
|
|
63
|
+
throw new errors_1.ValidationError('Username is too short', 'recipient');
|
|
64
|
+
}
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
// Check if it's a UUID (PNI: prefix or plain UUID)
|
|
68
|
+
const uuidRegex = /^(PNI:)?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
69
|
+
if (uuidRegex.test(recipient)) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
// Otherwise, validate as phone number
|
|
73
|
+
validatePhoneNumber(recipient);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Validates a message text
|
|
77
|
+
* @param message Message to validate
|
|
78
|
+
* @param maxLength Maximum message length
|
|
79
|
+
* @throws ValidationError if invalid
|
|
80
|
+
*/
|
|
81
|
+
function validateMessage(message, maxLength = 10000) {
|
|
82
|
+
if (message === undefined || message === null) {
|
|
83
|
+
throw new errors_1.ValidationError('Message is required', 'message');
|
|
84
|
+
}
|
|
85
|
+
if (typeof message !== 'string') {
|
|
86
|
+
throw new errors_1.ValidationError('Message must be a string', 'message');
|
|
87
|
+
}
|
|
88
|
+
if (message.length > maxLength) {
|
|
89
|
+
throw new errors_1.ValidationError(`Message exceeds maximum length of ${maxLength} characters`, 'message');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Validates file attachments
|
|
94
|
+
* @param attachments Array of attachment paths
|
|
95
|
+
* @throws ValidationError if invalid
|
|
96
|
+
*/
|
|
97
|
+
function validateAttachments(attachments) {
|
|
98
|
+
if (!Array.isArray(attachments)) {
|
|
99
|
+
throw new errors_1.ValidationError('Attachments must be an array', 'attachments');
|
|
100
|
+
}
|
|
101
|
+
for (const attachment of attachments) {
|
|
102
|
+
if (typeof attachment !== 'string') {
|
|
103
|
+
throw new errors_1.ValidationError('Each attachment must be a file path string', 'attachments');
|
|
104
|
+
}
|
|
105
|
+
if (attachment.length === 0) {
|
|
106
|
+
throw new errors_1.ValidationError('Attachment path cannot be empty', 'attachments');
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Validates a timestamp
|
|
112
|
+
* @param timestamp Timestamp to validate
|
|
113
|
+
* @throws ValidationError if invalid
|
|
114
|
+
*/
|
|
115
|
+
function validateTimestamp(timestamp) {
|
|
116
|
+
if (typeof timestamp !== 'number') {
|
|
117
|
+
throw new errors_1.ValidationError('Timestamp must be a number', 'timestamp');
|
|
118
|
+
}
|
|
119
|
+
if (timestamp <= 0) {
|
|
120
|
+
throw new errors_1.ValidationError('Timestamp must be positive', 'timestamp');
|
|
121
|
+
}
|
|
122
|
+
if (!Number.isFinite(timestamp)) {
|
|
123
|
+
throw new errors_1.ValidationError('Timestamp must be finite', 'timestamp');
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Validates an emoji string
|
|
128
|
+
* @param emoji Emoji to validate
|
|
129
|
+
* @throws ValidationError if invalid
|
|
130
|
+
*/
|
|
131
|
+
function validateEmoji(emoji) {
|
|
132
|
+
if (!emoji) {
|
|
133
|
+
throw new errors_1.ValidationError('Emoji is required', 'emoji');
|
|
134
|
+
}
|
|
135
|
+
if (typeof emoji !== 'string') {
|
|
136
|
+
throw new errors_1.ValidationError('Emoji must be a string', 'emoji');
|
|
137
|
+
}
|
|
138
|
+
// Basic emoji validation - should be a single grapheme cluster
|
|
139
|
+
if (emoji.length === 0 || emoji.length > 10) {
|
|
140
|
+
throw new errors_1.ValidationError('Invalid emoji format', 'emoji');
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Validates device ID
|
|
145
|
+
* @param deviceId Device ID to validate
|
|
146
|
+
* @throws ValidationError if invalid
|
|
147
|
+
*/
|
|
148
|
+
function validateDeviceId(deviceId) {
|
|
149
|
+
if (typeof deviceId !== 'number') {
|
|
150
|
+
throw new errors_1.ValidationError('Device ID must be a number', 'deviceId');
|
|
151
|
+
}
|
|
152
|
+
if (!Number.isInteger(deviceId)) {
|
|
153
|
+
throw new errors_1.ValidationError('Device ID must be an integer', 'deviceId');
|
|
154
|
+
}
|
|
155
|
+
if (deviceId <= 0) {
|
|
156
|
+
throw new errors_1.ValidationError('Device ID must be positive', 'deviceId');
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Sanitizes user input to prevent injection attacks
|
|
161
|
+
* @param input Input string to sanitize
|
|
162
|
+
* @returns Sanitized string
|
|
163
|
+
*/
|
|
164
|
+
function sanitizeInput(input) {
|
|
165
|
+
if (typeof input !== 'string') {
|
|
166
|
+
return '';
|
|
167
|
+
}
|
|
168
|
+
// Remove null bytes
|
|
169
|
+
return input.replace(/\0/g, '');
|
|
170
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "signal-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "A comprehensive TypeScript SDK for Signal Messenger with native JSON-RPC support, providing high-performance messaging, bot framework, and full signal-cli integration.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|