agora-token 2.0.4 → 2.0.6
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/.devcontainer/devcontainer.json +22 -0
- package/.prettierrc +12 -0
- package/index.d.ts +260 -26
- package/index.js +4 -1
- package/package.json +1 -1
- package/sample/AccessToken2Sample.js +29 -19
- package/sample/ConvoAITokenBuilderSample.js +36 -0
- package/sample/RtcTokenBuilder2Sample.js +16 -0
- package/sample/SttTokenBuilderSample.js +36 -0
- package/src/AccessToken2.js +366 -40
- package/src/ApaasTokenBuilder.js +9 -3
- package/src/ChatTokenBuilder.js +6 -2
- package/src/ConvoAITokenBuilder.js +68 -0
- package/src/EducationTokenBuilder.js +9 -3
- package/src/FpaTokenBuilder.js +1 -1
- package/src/RtcTokenBuilder2.js +124 -16
- package/src/RtmTokenBuilder2.js +25 -1
- package/src/SttTokenBuilder.js +68 -0
- package/test/AccessToken2Test.js +331 -4
- package/test/AccessTokenTest.js +62 -1
- package/test/ApaasTokenBuilderTest.js +8 -4
- package/test/ChatTokenBuilderTest.js +6 -4
- package/test/ConvoAITokenBuilderTest.js +58 -0
- package/test/DynamicKeyTest.js +4 -0
- package/test/EducationTokenBuilderTest.js +8 -4
- package/test/FpaTokenBuilderTest.js +2 -1
- package/test/RtcTokenBuilder2Test.js +74 -30
- package/test/RtmTokenBuilder2Test.js +53 -4
- package/test/RtmTokenBuilderTest.js +1 -0
- package/test/SttTokenBuilderTest.js +58 -0
- package/sample.js +0 -46
package/test/AccessToken2Test.js
CHANGED
|
@@ -3,7 +3,26 @@
|
|
|
3
3
|
* nodeunit AccessTokenTest.js
|
|
4
4
|
* see https://github.com/caolan/nodeunit
|
|
5
5
|
*/
|
|
6
|
-
const {
|
|
6
|
+
const {
|
|
7
|
+
AccessToken2,
|
|
8
|
+
Rtm2Permissions,
|
|
9
|
+
Service,
|
|
10
|
+
ServiceRtc,
|
|
11
|
+
ServiceRtm,
|
|
12
|
+
ServiceStreaming,
|
|
13
|
+
ServiceFCdn,
|
|
14
|
+
ServiceRtm2,
|
|
15
|
+
ServiceChat,
|
|
16
|
+
kRtcServiceType,
|
|
17
|
+
kRtmServiceType,
|
|
18
|
+
kStreamingServiceType,
|
|
19
|
+
kFCdnServiceType,
|
|
20
|
+
kRtm2ServiceType,
|
|
21
|
+
kChatServiceType
|
|
22
|
+
} = require('../src/AccessToken2')
|
|
23
|
+
const fs = require('fs')
|
|
24
|
+
const path = require('path')
|
|
25
|
+
const Module = require('module')
|
|
7
26
|
|
|
8
27
|
var appID = '970CA35de60c44645bbae8a215061b33'
|
|
9
28
|
var appCertificate = '5CFd2fd1755d40ecb72977518be15d3b'
|
|
@@ -15,6 +34,15 @@ var expire = 600
|
|
|
15
34
|
var salt = 1
|
|
16
35
|
var user_id = 'test_user'
|
|
17
36
|
|
|
37
|
+
// Represents an unsupported service type for forward compatibility tests.
|
|
38
|
+
class UnknownService extends Service {
|
|
39
|
+
// Creates a service whose type is not registered by AccessToken2.
|
|
40
|
+
constructor(serviceType = 999) {
|
|
41
|
+
super(serviceType)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Verifies deterministic RTC token generation with a numeric user ID.
|
|
18
46
|
exports.AccessToken_Test = function (test) {
|
|
19
47
|
var expected =
|
|
20
48
|
'007eJxTYBBbsMMnKq7p9Hf/HcIX5kce9b518kCiQgSr5Zrp4X1Tu6UUGCzNDZwdjU1TUs0Mkk1MzExMk5ISUy0SjQxNDcwMk4yN3b8IMEQwMTAwMoAwBIL4CgzmKeZGxmamqUmWFsYmFqbGluapxqnGaZYpJmYGSSkpiVwMRhYWRsYmhkbmxgDCaiTj'
|
|
@@ -30,7 +58,7 @@ exports.AccessToken_Test = function (test) {
|
|
|
30
58
|
test.done()
|
|
31
59
|
}
|
|
32
60
|
|
|
33
|
-
//
|
|
61
|
+
// Verifies deterministic RTC token generation with an empty user ID.
|
|
34
62
|
exports.AccessToken_Test2 = function (test) {
|
|
35
63
|
var expected =
|
|
36
64
|
'007eJxTYLhzZP08Lxa1Pg57+TcXb/3cZ3wi4V6kbpbOog0G2dOYk20UGCzNDZwdjU1TUs0Mkk1MzExMk5ISUy0SjQxNDcwMk4yN3b8IMEQwMTAwMoAwBIL4CgzmKeZGxmamqUmWFsYmFqbGluapxqnGaZYpJmYGSSkpiQwMADacImo='
|
|
@@ -46,7 +74,7 @@ exports.AccessToken_Test2 = function (test) {
|
|
|
46
74
|
test.done()
|
|
47
75
|
}
|
|
48
76
|
|
|
49
|
-
//
|
|
77
|
+
// Verifies deterministic RTC token generation with a string user account.
|
|
50
78
|
exports.AccessToken_Test3 = function (test) {
|
|
51
79
|
var expected =
|
|
52
80
|
'007eJxTYBBbsMMnKq7p9Hf/HcIX5kce9b518kCiQgSr5Zrp4X1Tu6UUGCzNDZwdjU1TUs0Mkk1MzExMk5ISUy0SjQxNDcwMk4yN3b8IMEQwMTAwMoAwBIL4CgzmKeZGxmamqUmWFsYmFqbGluapxqnGaZYpJmYGSSkpiVwMRhYWRsYmhkbmxgDCaiTj'
|
|
@@ -62,7 +90,7 @@ exports.AccessToken_Test3 = function (test) {
|
|
|
62
90
|
test.done()
|
|
63
91
|
}
|
|
64
92
|
|
|
65
|
-
//
|
|
93
|
+
// Verifies deterministic token generation with distinct service types.
|
|
66
94
|
exports.AccessToken_Test4 = function (test) {
|
|
67
95
|
var expected =
|
|
68
96
|
'007eJxTYOAQsrQ5s3TfH+1tvy8zZZ46EpCc0V43JXdGd2jS8porKo4KDJbmBs6OxqYpqWYGySYmZiamSUmJqRaJRoamBmaGScbG7l8EGCKYGBgYGRgYmBgYGVgYGMF8JjDJDCZZwKQCg3mKuZGxmWlqkqWFsYmFqbGleapxqnGaZYqJmUFSSkoiF4ORhYWRsYmhkbkxyCyISZwMJanFJfGlxalFACKnKng='
|
|
@@ -85,6 +113,7 @@ exports.AccessToken_Test4 = function (test) {
|
|
|
85
113
|
test.done()
|
|
86
114
|
}
|
|
87
115
|
|
|
116
|
+
// Verifies deterministic Chat user token generation.
|
|
88
117
|
exports.AccessToken_Test_buildChatUserToken = function (test) {
|
|
89
118
|
var expected =
|
|
90
119
|
'007eJxTYNAIsnbS3v/A5t2TC6feR15r+6cq8bqAvfaW+tk/Vzz+p6xTYLA0N3B2NDZNSTUzSDYxMTMxTUpKTLVINDI0NTAzTDI2dv8iwBDBxMDAyADCrAyMDIxgPheDkYWFkbGJoZG5MQAfpR64'
|
|
@@ -100,6 +129,7 @@ exports.AccessToken_Test_buildChatUserToken = function (test) {
|
|
|
100
129
|
test.done()
|
|
101
130
|
}
|
|
102
131
|
|
|
132
|
+
// Verifies deterministic Chat application token generation.
|
|
103
133
|
exports.AccessToken_Test_buildChatAppToken = function (test) {
|
|
104
134
|
var expected =
|
|
105
135
|
'007eJxTYNDNaz3snC8huEfHWdz6s98qltq4zqy9fl99Uh0FDvy6F6DAYGlu4OxobJqSamaQbGJiZmKalJSYapFoZGhqYGaYZGzs/kWAIYKJgYGRAYRZGRgZmMB8BgYArfIYaw=='
|
|
@@ -114,3 +144,300 @@ exports.AccessToken_Test_buildChatAppToken = function (test) {
|
|
|
114
144
|
test.equal(expected, actual)
|
|
115
145
|
test.done()
|
|
116
146
|
}
|
|
147
|
+
|
|
148
|
+
// Preserves repeated service types and their insertion order after parsing.
|
|
149
|
+
exports.AccessToken_Test_repeatedServiceTypes = function (test) {
|
|
150
|
+
const token = new AccessToken2(appID, appCertificate, ts, expire)
|
|
151
|
+
token.salt = salt
|
|
152
|
+
|
|
153
|
+
const rtmService = new ServiceRtm(user_id)
|
|
154
|
+
rtmService.add_privilege(ServiceRtm.kPrivilegeLogin, expire + 50)
|
|
155
|
+
token.add_service(rtmService)
|
|
156
|
+
|
|
157
|
+
const rtcService = new ServiceRtc(channel, uid)
|
|
158
|
+
rtcService.add_privilege(ServiceRtc.kPrivilegeJoinChannel, expire)
|
|
159
|
+
token.add_service(rtcService)
|
|
160
|
+
|
|
161
|
+
const streamRtcService = new ServiceRtc('stream-channel', 'stream-user')
|
|
162
|
+
streamRtcService.add_privilege(ServiceRtc.kPrivilegeJoinChannel, expire + 100)
|
|
163
|
+
streamRtcService.add_privilege(ServiceRtc.kPrivilegePublishDataStream, expire + 100)
|
|
164
|
+
token.add_service(streamRtcService)
|
|
165
|
+
|
|
166
|
+
const encoded = token.build()
|
|
167
|
+
test.equal(3, token.services.length)
|
|
168
|
+
test.strictEqual(rtmService, token.services[0])
|
|
169
|
+
test.equal(2, token.getServices(kRtcServiceType).length)
|
|
170
|
+
|
|
171
|
+
const parsed = new AccessToken2('', '', 0, 0)
|
|
172
|
+
test.equal(true, parsed.from_string(encoded))
|
|
173
|
+
const rtcServices = parsed.getServices(kRtcServiceType)
|
|
174
|
+
test.equal(2, rtcServices.length)
|
|
175
|
+
test.equal(channel, rtcServices[0].__channel_name.toString())
|
|
176
|
+
test.equal('stream-channel', rtcServices[1].__channel_name.toString())
|
|
177
|
+
test.equal(expire + 100, rtcServices[1].__privileges[ServiceRtc.kPrivilegePublishDataStream])
|
|
178
|
+
test.equal(1, parsed.getServices(kRtmServiceType).length)
|
|
179
|
+
test.equal(0, parsed.getServices(kChatServiceType).length)
|
|
180
|
+
test.equal(true, parsed.verifySignature(appCertificate))
|
|
181
|
+
test.equal(false, parsed.verifySignature('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'))
|
|
182
|
+
test.done()
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Parses and verifies C++ Streaming, FCDN, and RTM2 services.
|
|
186
|
+
exports.AccessToken_Test_extendedServicesFromCpp = function (test) {
|
|
187
|
+
const encoded = '007eJxTYPj86Lzdz79M25wNn/lMfvu+TkfmdpiviKvChm8ZV3SWndytwGBpbuDsaGyakmpmkGxiYmZimpSUmGqRaGRoamBmmGRs7P5FgCGCiYGBkYGBgRkImYAsEJ8JTCowmKeYGxmbmaYmWVoYm1iYGluapxqnGqdZppiYGSSlpCRyMRhZWBgZmxgamRuzUaSbA6gXopuToSS1uCS+tDi1iJkB4jQmoGBuanFxYnqqbiKCmcTIAIEcDMUlRamJubqJLGD1jAxsDCD9uokAO/VDvQ=='
|
|
188
|
+
const parsed = new AccessToken2('', '', 0, 0)
|
|
189
|
+
|
|
190
|
+
test.equal(true, parsed.from_string(encoded))
|
|
191
|
+
test.equal(true, parsed.verifySignature(appCertificate))
|
|
192
|
+
|
|
193
|
+
const streaming = parsed.getServices(kStreamingServiceType)[0]
|
|
194
|
+
test.equal(channel, streaming.__channel_name.toString())
|
|
195
|
+
test.equal(uidStr, streaming.__account.toString())
|
|
196
|
+
test.equal(expire, streaming.__privileges[ServiceStreaming.kPrivilegePublishMixStream])
|
|
197
|
+
test.equal(expire, streaming.__privileges[ServiceStreaming.kPrivilegePublishRawStream])
|
|
198
|
+
|
|
199
|
+
const fcdn = parsed.getServices(kFCdnServiceType)[0]
|
|
200
|
+
test.equal(channel, fcdn.__channel_name.toString())
|
|
201
|
+
test.equal(uidStr, fcdn.__account.toString())
|
|
202
|
+
test.equal(expire, fcdn.__privileges[ServiceFCdn.kPrivilegePublish])
|
|
203
|
+
test.equal(expire, fcdn.__privileges[ServiceFCdn.kPrivilegePlay])
|
|
204
|
+
|
|
205
|
+
const rtm2 = parsed.getServices(kRtm2ServiceType)[0]
|
|
206
|
+
test.equal(user_id, rtm2.__user_id.toString())
|
|
207
|
+
test.deepEqual({
|
|
208
|
+
0: { 0: ['message-a', 'message-b'] },
|
|
209
|
+
1: { 1: ['stream-a'] },
|
|
210
|
+
4: { 0: ['user-a'] }
|
|
211
|
+
}, rtm2.__permissions.details)
|
|
212
|
+
test.equal(expire, rtm2.__privileges[ServiceRtm2.kPrivilegeLogin])
|
|
213
|
+
test.done()
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Verifies deterministic Streaming and FCDN generation and UID conversion against C++.
|
|
217
|
+
exports.AccessToken_Test_extendedServiceNumericUidConversion = function (test) {
|
|
218
|
+
const token = new AccessToken2(appID, appCertificate, ts, expire)
|
|
219
|
+
token.salt = salt
|
|
220
|
+
const streamingUid = new ServiceStreaming(channel, uid)
|
|
221
|
+
streamingUid.add_privilege(ServiceStreaming.kPrivilegePublishMixStream, expire)
|
|
222
|
+
token.add_service(streamingUid)
|
|
223
|
+
const streamingWildcard = new ServiceStreaming(channel, 0)
|
|
224
|
+
streamingWildcard.add_privilege(ServiceStreaming.kPrivilegePublishRawStream, expire)
|
|
225
|
+
token.add_service(streamingWildcard)
|
|
226
|
+
const streamingAccount = new ServiceStreaming(channel, 'stream-account')
|
|
227
|
+
streamingAccount.add_privilege(ServiceStreaming.kPrivilegePublishMixStream, expire)
|
|
228
|
+
streamingAccount.add_privilege(ServiceStreaming.kPrivilegePublishRawStream, expire)
|
|
229
|
+
token.add_service(streamingAccount)
|
|
230
|
+
const fcdnUid = new ServiceFCdn(channel, uid)
|
|
231
|
+
fcdnUid.add_privilege(ServiceFCdn.kPrivilegePublish, expire)
|
|
232
|
+
token.add_service(fcdnUid)
|
|
233
|
+
const fcdnWildcard = new ServiceFCdn(channel, 0)
|
|
234
|
+
fcdnWildcard.add_privilege(ServiceFCdn.kPrivilegePlay, expire)
|
|
235
|
+
token.add_service(fcdnWildcard)
|
|
236
|
+
const fcdnAccount = new ServiceFCdn(channel, 'fcdn-account')
|
|
237
|
+
fcdnAccount.add_privilege(ServiceFCdn.kPrivilegePublish, expire)
|
|
238
|
+
fcdnAccount.add_privilege(ServiceFCdn.kPrivilegePlay, expire)
|
|
239
|
+
token.add_service(fcdnAccount)
|
|
240
|
+
|
|
241
|
+
const encoded = token.build()
|
|
242
|
+
test.equal(
|
|
243
|
+
encoded,
|
|
244
|
+
'007eJxTYLi93GuuUHrO9Fr71KVJKqfDby8RezlVfGLMO77DIl79U40UGCzNDZwdjU1TUs0Mkk1MzExMk5ISUy0SjQxNDcwMk4yN3b8IMEQwMTAwMjAwsDEwMzAyMIL5CgzmKeZGxmamqUmWFsYmFqbGluapxqnGaZYpJmYGSSkpiVwMRhYWRsYmhkbmxiB9TETqY2BgZmCC2kKsHj6G4pKi1MRc3cTk5PzSvBI2Mt3JRpI72Uh2Jw9DWnJKHsyVAElvX1c='
|
|
245
|
+
)
|
|
246
|
+
const parsed = new AccessToken2('', '', 0, 0)
|
|
247
|
+
test.equal(true, parsed.from_string(encoded))
|
|
248
|
+
test.deepEqual(
|
|
249
|
+
parsed.getServices(kStreamingServiceType).map(service => service.__account.toString()),
|
|
250
|
+
[uidStr, '', 'stream-account']
|
|
251
|
+
)
|
|
252
|
+
test.deepEqual(
|
|
253
|
+
parsed.getServices(kFCdnServiceType).map(service => service.__account.toString()),
|
|
254
|
+
[uidStr, '', 'fcdn-account']
|
|
255
|
+
)
|
|
256
|
+
test.done()
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Generates and parses an RTM2 token whose uncompressed payload exceeds the initial buffer capacity.
|
|
260
|
+
exports.AccessToken_Test_largeRtm2PermissionPayload = function (test) {
|
|
261
|
+
const resources = Array.from({ length: 160 }, (_, index) => `resource-${index.toString().padStart(4, '0')}`)
|
|
262
|
+
const permissions = new Rtm2Permissions()
|
|
263
|
+
permissions.add(Rtm2Permissions.kUsers, Rtm2Permissions.kRead, resources)
|
|
264
|
+
|
|
265
|
+
const token = new AccessToken2(appID, appCertificate, ts, expire)
|
|
266
|
+
token.salt = salt
|
|
267
|
+
const rtm2Service = new ServiceRtm2(user_id, permissions)
|
|
268
|
+
rtm2Service.add_privilege(ServiceRtm2.kPrivilegeLogin, expire)
|
|
269
|
+
token.add_service(rtm2Service)
|
|
270
|
+
|
|
271
|
+
const parsed = new AccessToken2('', '', 0, 0)
|
|
272
|
+
test.equal(true, parsed.from_string(token.build()))
|
|
273
|
+
test.equal(true, parsed.verifySignature(appCertificate))
|
|
274
|
+
test.deepEqual(resources, parsed.getServices(kRtm2ServiceType)[0].__permissions.details[Rtm2Permissions.kUsers][Rtm2Permissions.kRead])
|
|
275
|
+
test.done()
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Keeps known services parsed before an unknown service type.
|
|
279
|
+
exports.AccessToken_Test_unknownServiceAfterKnownService = function (test) {
|
|
280
|
+
const token = new AccessToken2(appID, appCertificate, ts, expire)
|
|
281
|
+
token.salt = salt
|
|
282
|
+
|
|
283
|
+
const rtcService = new ServiceRtc(channel, uid)
|
|
284
|
+
rtcService.add_privilege(ServiceRtc.kPrivilegeJoinChannel, expire)
|
|
285
|
+
token.add_service(rtcService)
|
|
286
|
+
|
|
287
|
+
const unknownService = new UnknownService()
|
|
288
|
+
unknownService.add_privilege(1, expire)
|
|
289
|
+
token.add_service(unknownService)
|
|
290
|
+
|
|
291
|
+
const parsed = new AccessToken2('', '', 0, 0)
|
|
292
|
+
test.equal(true, parsed.from_string(token.build()))
|
|
293
|
+
test.equal(1, parsed.getServices(kRtcServiceType).length)
|
|
294
|
+
test.equal(0, parsed.getServices(999).length)
|
|
295
|
+
test.equal(true, parsed.verifySignature(appCertificate))
|
|
296
|
+
test.done()
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Stops before known services that follow an unknown service payload.
|
|
300
|
+
exports.AccessToken_Test_unknownServiceBeforeKnownService = function (test) {
|
|
301
|
+
const token = new AccessToken2(appID, appCertificate, ts, expire)
|
|
302
|
+
token.salt = salt
|
|
303
|
+
|
|
304
|
+
const rtcService = new ServiceRtc(channel, uid)
|
|
305
|
+
rtcService.add_privilege(ServiceRtc.kPrivilegeJoinChannel, expire)
|
|
306
|
+
token.add_service(rtcService)
|
|
307
|
+
|
|
308
|
+
const unknownService = new UnknownService(0)
|
|
309
|
+
unknownService.add_privilege(1, expire)
|
|
310
|
+
token.add_service(unknownService)
|
|
311
|
+
|
|
312
|
+
const parsed = new AccessToken2('', '', 0, 0)
|
|
313
|
+
test.equal(true, parsed.from_string(token.build()))
|
|
314
|
+
test.equal(0, parsed.getServices(kRtcServiceType).length)
|
|
315
|
+
test.equal(true, parsed.verifySignature(appCertificate))
|
|
316
|
+
test.done()
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// Parses an old token and replaces services from an earlier parse.
|
|
320
|
+
exports.AccessToken_Test_parseOldTokenAndClearServices = function (test) {
|
|
321
|
+
const token = new AccessToken2(appID, appCertificate, ts, expire)
|
|
322
|
+
token.salt = salt
|
|
323
|
+
const rtmService = new ServiceRtm(user_id)
|
|
324
|
+
rtmService.add_privilege(ServiceRtm.kPrivilegeLogin, expire)
|
|
325
|
+
token.add_service(rtmService)
|
|
326
|
+
|
|
327
|
+
const parsed = new AccessToken2('', '', 0, 0)
|
|
328
|
+
test.equal(true, parsed.from_string(token.build()))
|
|
329
|
+
test.equal(1, parsed.getServices(kRtmServiceType).length)
|
|
330
|
+
|
|
331
|
+
const oldToken =
|
|
332
|
+
'007eJxTYBBbsMMnKq7p9Hf/HcIX5kce9b518kCiQgSr5Zrp4X1Tu6UUGCzNDZwdjU1TUs0Mkk1MzExMk5ISUy0SjQxNDcwMk4yN3b8IMEQwMTAwMoAwBIL4CgzmKeZGxmamqUmWFsYmFqbGluapxqnGaZYpJmYGSSkpiVwMRhYWRsYmhkbmxgDCaiTj'
|
|
333
|
+
test.equal(true, parsed.from_string(oldToken))
|
|
334
|
+
test.equal(1, parsed.services.length)
|
|
335
|
+
test.equal(1, parsed.getServices(kRtcServiceType).length)
|
|
336
|
+
test.equal(0, parsed.getServices(kRtmServiceType).length)
|
|
337
|
+
test.equal(true, parsed.verifySignature(appCertificate))
|
|
338
|
+
test.done()
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Rejects signature verification before parsing or with invalid certificates.
|
|
342
|
+
exports.AccessToken_Test_verifySignaturePreconditions = function (test) {
|
|
343
|
+
const parsed = new AccessToken2('', '', 0, 0)
|
|
344
|
+
test.equal(false, parsed.verifySignature(appCertificate))
|
|
345
|
+
|
|
346
|
+
const token = new AccessToken2(appID, appCertificate, ts, expire)
|
|
347
|
+
token.salt = salt
|
|
348
|
+
const rtcService = new ServiceRtc(channel, uid)
|
|
349
|
+
rtcService.add_privilege(ServiceRtc.kPrivilegeJoinChannel, expire)
|
|
350
|
+
token.add_service(rtcService)
|
|
351
|
+
|
|
352
|
+
test.equal(true, parsed.from_string(token.build()))
|
|
353
|
+
test.equal(false, parsed.verifySignature(null))
|
|
354
|
+
test.equal(false, parsed.verifySignature('invalid'))
|
|
355
|
+
test.equal(false, parsed.verifySignature('zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz'))
|
|
356
|
+
test.equal(true, parsed.verifySignature(appCertificate))
|
|
357
|
+
|
|
358
|
+
test.equal(false, parsed.from_string('006invalid'))
|
|
359
|
+
test.equal(false, parsed.verifySignature(appCertificate))
|
|
360
|
+
test.equal(0, parsed.services.length)
|
|
361
|
+
test.done()
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// Sorts distinct service types before packing without changing insertion order.
|
|
365
|
+
exports.AccessToken_Test_stableServiceTypeOrdering = function (test) {
|
|
366
|
+
const token = new AccessToken2(appID, appCertificate, ts, expire)
|
|
367
|
+
token.salt = salt
|
|
368
|
+
|
|
369
|
+
const rtmService = new ServiceRtm(user_id)
|
|
370
|
+
rtmService.add_privilege(ServiceRtm.kPrivilegeLogin, expire)
|
|
371
|
+
token.add_service(rtmService)
|
|
372
|
+
|
|
373
|
+
const rtcService = new ServiceRtc(channel, uid)
|
|
374
|
+
rtcService.add_privilege(ServiceRtc.kPrivilegeJoinChannel, expire)
|
|
375
|
+
rtcService.add_privilege(ServiceRtc.kPrivilegePublishAudioStream, expire)
|
|
376
|
+
rtcService.add_privilege(ServiceRtc.kPrivilegePublishVideoStream, expire)
|
|
377
|
+
rtcService.add_privilege(ServiceRtc.kPrivilegePublishDataStream, expire)
|
|
378
|
+
token.add_service(rtcService)
|
|
379
|
+
|
|
380
|
+
const expected =
|
|
381
|
+
'007eJxTYOAQsrQ5s3TfH+1tvy8zZZ46EpCc0V43JXdGd2jS8porKo4KDJbmBs6OxqYpqWYGySYmZiamSUmJqRaJRoamBmaGScbG7l8EGCKYGBgYGRgYmBgYGVgYGMF8JjDJDCZZwKQCg3mKuZGxmWlqkqWFsYmFqbGleapxqnGaZYqJmUFSSkoiF4ORhYWRsYmhkbkxyCyISZwMJanFJfGlxalFACKnKng='
|
|
382
|
+
test.equal(expected, token.build())
|
|
383
|
+
test.strictEqual(rtmService, token.services[0])
|
|
384
|
+
test.done()
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// Rejects invalid build fields, non-string tokens, and malformed Token007 payloads.
|
|
388
|
+
exports.AccessToken_Test_invalidBuildAndParseInputs = function (test) {
|
|
389
|
+
const empty = new AccessToken2(appID, appCertificate, ts, expire)
|
|
390
|
+
test.equal('', empty.build())
|
|
391
|
+
|
|
392
|
+
const invalid = new AccessToken2('invalid', appCertificate, ts, expire)
|
|
393
|
+
const service = new ServiceRtc(channel, uid)
|
|
394
|
+
service.add_privilege(ServiceRtc.kPrivilegeJoinChannel, expire)
|
|
395
|
+
invalid.add_service(service)
|
|
396
|
+
test.equal('', invalid.build())
|
|
397
|
+
|
|
398
|
+
const parsed = new AccessToken2('', '', 0, 0)
|
|
399
|
+
test.equal(false, parsed.from_string(null))
|
|
400
|
+
test.equal(false, parsed.from_string('00'))
|
|
401
|
+
test.equal(false, parsed.from_string('007invalid'))
|
|
402
|
+
test.done()
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// Rejects verification when the parsed signature length is altered.
|
|
406
|
+
exports.AccessToken_Test_signatureLengthMismatch = function (test) {
|
|
407
|
+
const token = new AccessToken2(appID, appCertificate, ts, expire)
|
|
408
|
+
token.salt = salt
|
|
409
|
+
const service = new ServiceRtc(channel, uid)
|
|
410
|
+
service.add_privilege(ServiceRtc.kPrivilegeJoinChannel, expire)
|
|
411
|
+
token.add_service(service)
|
|
412
|
+
|
|
413
|
+
const parsed = new AccessToken2('', '', 0, 0)
|
|
414
|
+
test.equal(true, parsed.from_string(token.build()))
|
|
415
|
+
parsed.__signature = Buffer.alloc(1)
|
|
416
|
+
test.equal(false, parsed.verifySignature(appCertificate))
|
|
417
|
+
test.done()
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// Exercises private buffer helpers that are retained for wire-format compatibility.
|
|
421
|
+
exports.AccessToken_Test_bufferHelpers = function (test) {
|
|
422
|
+
const filename = path.resolve(__dirname, '../src/AccessToken2.js')
|
|
423
|
+
const source = fs.readFileSync(filename, 'utf8') +
|
|
424
|
+
'\nmodule.exports.__ByteBuf = ByteBuf; module.exports.__ReadByteBuf = ReadByteBuf;'
|
|
425
|
+
const internalModule = new Module(filename, module)
|
|
426
|
+
internalModule.filename = filename
|
|
427
|
+
internalModule.paths = Module._nodeModulePaths(path.dirname(filename))
|
|
428
|
+
internalModule._compile(source, filename)
|
|
429
|
+
const ByteBuf = internalModule.exports.__ByteBuf
|
|
430
|
+
const ReadByteBuf = internalModule.exports.__ReadByteBuf
|
|
431
|
+
|
|
432
|
+
const signed = new ByteBuf().putInt32(-7).putInt16(-2).pack()
|
|
433
|
+
test.equal(-7, signed.readInt32LE(0))
|
|
434
|
+
test.equal(-2, signed.readInt16LE(4))
|
|
435
|
+
test.equal(2, new ByteBuf().putTreeMap(null).pack().length)
|
|
436
|
+
test.equal(2, new ByteBuf().putTreeMapUInt32(null).pack().length)
|
|
437
|
+
test.ok(new ByteBuf().putTreeMap({ 1: 'value' }).pack().length > 2)
|
|
438
|
+
|
|
439
|
+
const reader = new ReadByteBuf(Buffer.from([1, 0, 2, 0, 0, 0]))
|
|
440
|
+
test.equal(1, reader.getUint16())
|
|
441
|
+
test.equal(2, reader.getUint32())
|
|
442
|
+
test.done()
|
|
443
|
+
}
|
package/test/AccessTokenTest.js
CHANGED
|
@@ -5,6 +5,11 @@
|
|
|
5
5
|
*/
|
|
6
6
|
const AccessToken = require("../src/AccessToken").AccessToken;
|
|
7
7
|
const Priviledges = require("../src/AccessToken").priviledges;
|
|
8
|
+
const RtcTokenBuilder = require('../src/RtcTokenBuilder').RtcTokenBuilder;
|
|
9
|
+
const SignalingToken = require('../src/SignalingToken');
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const path = require('path');
|
|
12
|
+
const Module = require('module');
|
|
8
13
|
|
|
9
14
|
const appID = "970CA35de60c44645bbae8a215061b33";
|
|
10
15
|
const appCertificate = "5CFd2fd1755d40ecb72977518be15d3b";
|
|
@@ -14,6 +19,7 @@ const salt = 1;
|
|
|
14
19
|
const ts = 1111111;
|
|
15
20
|
const expireTimestamp = 1446455471;
|
|
16
21
|
|
|
22
|
+
// Verifies deterministic legacy AccessToken generation.
|
|
17
23
|
exports.AccessToken_Test = function (test) {
|
|
18
24
|
const expected = "006970CA35de60c44645bbae8a215061b33IACV0fZUBw+72cVoL9eyGGh3Q6Poi8bgjwVLnyKSJyOXR7dIfRBXoFHlEAABAAAAR/QQAAEAAQCvKDdW";
|
|
19
25
|
|
|
@@ -27,7 +33,7 @@ exports.AccessToken_Test = function (test) {
|
|
|
27
33
|
test.done();
|
|
28
34
|
};
|
|
29
35
|
|
|
30
|
-
//
|
|
36
|
+
// Verifies deterministic legacy AccessToken generation with an empty user ID.
|
|
31
37
|
exports.AccessToken_Test2 = function (test) {
|
|
32
38
|
const expected = "006970CA35de60c44645bbae8a215061b33IACw1o7htY6ISdNRtku3p9tjTPi0jCKf9t49UHJhzCmL6bdIfRAAAAAAEAABAAAAR/QQAAEAAQCvKDdW";
|
|
33
39
|
|
|
@@ -44,6 +50,7 @@ exports.AccessToken_Test2 = function (test) {
|
|
|
44
50
|
|
|
45
51
|
const RtcRole = require("../src/RtcTokenBuilder").Role;
|
|
46
52
|
|
|
53
|
+
// Verifies deterministic legacy RTC token generation.
|
|
47
54
|
exports.RtcTokenBuilder_Test = function (test) {
|
|
48
55
|
const appID = "970CA35de60c44645bbae8a215061b33";
|
|
49
56
|
const certificate = "5CFd2fd1755d40ecb72977518be15d3b";
|
|
@@ -75,3 +82,57 @@ exports.RtcTokenBuilder_Test = function (test) {
|
|
|
75
82
|
test.equal(expected, actual);
|
|
76
83
|
test.done();
|
|
77
84
|
};
|
|
85
|
+
|
|
86
|
+
// Verifies legacy token parsing and malformed input handling.
|
|
87
|
+
exports.AccessToken_Parse_Test = function (test) {
|
|
88
|
+
const key = new AccessToken(appID, appCertificate, channel, uid);
|
|
89
|
+
key.salt = salt;
|
|
90
|
+
key.ts = ts;
|
|
91
|
+
key.addPriviledge(Priviledges.kJoinChannel, expireTimestamp);
|
|
92
|
+
|
|
93
|
+
const parsed = new AccessToken('', '', '', '');
|
|
94
|
+
test.equal(true, parsed.fromString(key.build()));
|
|
95
|
+
test.equal(expireTimestamp, parsed.messages[Priviledges.kJoinChannel]);
|
|
96
|
+
test.equal(false, parsed.fromString('007invalid'));
|
|
97
|
+
test.equal(false, parsed.fromString('006' + appID + '!'));
|
|
98
|
+
test.done();
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
// Verifies both public legacy RTC builder entry points.
|
|
102
|
+
exports.RtcTokenBuilder_PublicMethods_Test = function (test) {
|
|
103
|
+
const uidToken = RtcTokenBuilder.buildTokenWithUid(
|
|
104
|
+
appID, appCertificate, channel, uid, RtcRole.PUBLISHER, expireTimestamp);
|
|
105
|
+
const accountToken = RtcTokenBuilder.buildTokenWithAccount(
|
|
106
|
+
appID, appCertificate, channel, String(uid), RtcRole.SUBSCRIBER, expireTimestamp);
|
|
107
|
+
|
|
108
|
+
test.equal(true, new AccessToken('', '', '', '').fromString(uidToken));
|
|
109
|
+
test.equal(true, new AccessToken('', '', '', '').fromString(accountToken));
|
|
110
|
+
test.done();
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
// Verifies signaling token generation for explicit and one-day lifetimes.
|
|
114
|
+
exports.SignalingToken_Test = function (test) {
|
|
115
|
+
const token = SignalingToken.get(appID, appCertificate, String(uid), 60);
|
|
116
|
+
const oneDayToken = SignalingToken.get1DayToken(appID, appCertificate, String(uid));
|
|
117
|
+
|
|
118
|
+
test.equal(4, token.split(':').length);
|
|
119
|
+
test.equal(appID, token.split(':')[1]);
|
|
120
|
+
test.equal(4, oneDayToken.split(':').length);
|
|
121
|
+
test.done();
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
// Exercises legacy private map writers retained by the Token006 wire format.
|
|
125
|
+
exports.AccessToken_BufferHelpers_Test = function (test) {
|
|
126
|
+
const filename = path.resolve(__dirname, '../src/AccessToken.js');
|
|
127
|
+
const source = fs.readFileSync(filename, 'utf8') + '\nmodule.exports.__ByteBuf = ByteBuf;';
|
|
128
|
+
const internalModule = new Module(filename, module);
|
|
129
|
+
internalModule.filename = filename;
|
|
130
|
+
internalModule.paths = Module._nodeModulePaths(path.dirname(filename));
|
|
131
|
+
internalModule._compile(source, filename);
|
|
132
|
+
const ByteBuf = internalModule.exports.__ByteBuf;
|
|
133
|
+
|
|
134
|
+
test.equal(2, new ByteBuf().putTreeMap(null).pack().length);
|
|
135
|
+
test.ok(new ByteBuf().putTreeMap({ 1: 'value' }).pack().length > 2);
|
|
136
|
+
test.equal(2, new ByteBuf().putTreeMapUInt32(null).pack().length);
|
|
137
|
+
test.done();
|
|
138
|
+
};
|
|
@@ -12,18 +12,21 @@ const roomUuid = '123'
|
|
|
12
12
|
const userUuid = '2882341273'
|
|
13
13
|
const role = 1
|
|
14
14
|
|
|
15
|
+
// Verifies APaaS room-user token generation and parsing.
|
|
15
16
|
exports.BuildRoomUserToken_Test = function (test) {
|
|
16
17
|
let accessToken = new AccessToken2('', '', 0, 0)
|
|
17
18
|
let token = ApaasTokenBuilder.buildRoomUserToken(appId, appCertificate, roomUuid, userUuid, role, expire)
|
|
18
19
|
accessToken.from_string(token)
|
|
20
|
+
const service = accessToken.getServices(kApaasServiceType)[0]
|
|
19
21
|
test.equal(appId, accessToken.appId)
|
|
20
22
|
test.equal(expire, accessToken.expire)
|
|
21
|
-
test.equal(roomUuid,
|
|
22
|
-
test.equal(userUuid,
|
|
23
|
-
test.equal(role,
|
|
23
|
+
test.equal(roomUuid, service.__room_uuid)
|
|
24
|
+
test.equal(userUuid, service.__user_uuid)
|
|
25
|
+
test.equal(role, service.__role)
|
|
24
26
|
test.done()
|
|
25
27
|
}
|
|
26
28
|
|
|
29
|
+
// Verifies APaaS user token generation and parsing.
|
|
27
30
|
exports.BuildUserToken_Test = function (test) {
|
|
28
31
|
let accessToken = new AccessToken2('', '', 0, 0)
|
|
29
32
|
let token = ApaasTokenBuilder.buildUserToken(appId, appCertificate, userUuid, expire)
|
|
@@ -31,10 +34,11 @@ exports.BuildUserToken_Test = function (test) {
|
|
|
31
34
|
|
|
32
35
|
test.equal(appId, accessToken.appId)
|
|
33
36
|
test.equal(expire, accessToken.expire)
|
|
34
|
-
test.equal(userUuid, accessToken.
|
|
37
|
+
test.equal(userUuid, accessToken.getServices(kApaasServiceType)[0].__user_uuid)
|
|
35
38
|
test.done()
|
|
36
39
|
}
|
|
37
40
|
|
|
41
|
+
// Verifies APaaS application token generation and parsing.
|
|
38
42
|
exports.BuildAppToken_Test = function (test) {
|
|
39
43
|
let accessToken = new AccessToken2('', '', 0, 0)
|
|
40
44
|
let token = ApaasTokenBuilder.buildAppToken(appId, appCertificate, expire)
|
|
@@ -11,24 +11,26 @@ const appCertificate = "5CFd2fd1755d40ecb72977518be15d3b";
|
|
|
11
11
|
const userUuid = "2882341273";
|
|
12
12
|
const expire = 600;
|
|
13
13
|
|
|
14
|
+
// Verifies Chat user token generation and parsing.
|
|
14
15
|
exports.buildUserToken_Test = function (test) {
|
|
15
16
|
let token = ChatTokenBuilder.buildUserToken(appId, appCertificate, userUuid, expire);
|
|
16
17
|
let accessToken = new AccessToken2("", "", 0, 0);
|
|
17
18
|
accessToken.from_string(token);
|
|
19
|
+
const service = accessToken.getServices(kChatServiceType)[0];
|
|
18
20
|
test.equal(appId, accessToken.appId);
|
|
19
21
|
test.equal(expire, accessToken.expire);
|
|
20
|
-
test.equal(userUuid,
|
|
21
|
-
test.equal(expire,
|
|
22
|
+
test.equal(userUuid, service.__user_id);
|
|
23
|
+
test.equal(expire, service.__privileges[ServiceChat.kPrivilegeUser]);
|
|
22
24
|
test.done();
|
|
23
25
|
};
|
|
24
26
|
|
|
27
|
+
// Verifies Chat application token generation and parsing.
|
|
25
28
|
exports.buildAppToken_Test = function (test) {
|
|
26
29
|
let token = ChatTokenBuilder.buildAppToken(appId, appCertificate, expire);
|
|
27
30
|
let accessToken = new AccessToken2("", "", 0, 0);
|
|
28
31
|
accessToken.from_string(token);
|
|
29
32
|
test.equal(appId, accessToken.appId);
|
|
30
33
|
test.equal(expire, accessToken.expire);
|
|
31
|
-
test.equal(expire, accessToken.
|
|
34
|
+
test.equal(expire, accessToken.getServices(kChatServiceType)[0].__privileges[ServiceChat.kPrivilegeApp]);
|
|
32
35
|
test.done();
|
|
33
36
|
}
|
|
34
|
-
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* run this test with command:
|
|
3
|
+
* nodeunit test/ConvoAITokenBuilderTest.js
|
|
4
|
+
*/
|
|
5
|
+
const { ConvoAITokenBuilder } = require('../src/ConvoAITokenBuilder')
|
|
6
|
+
const { AccessToken2, kConvoAIServiceType, kRtcServiceType, kRtmServiceType, ServiceRtc, ServiceRtm } = require('../src/AccessToken2')
|
|
7
|
+
const { Role } = require('../src/RtcTokenBuilder2')
|
|
8
|
+
|
|
9
|
+
const appId = '970CA35de60c44645bbae8a215061b33'
|
|
10
|
+
const appCertificate = '5CFd2fd1755d40ecb72977518be15d3b'
|
|
11
|
+
const channelName = '7d72365eb983485397e3e3f9d460bdda'
|
|
12
|
+
const rtcAccount = '2882341273'
|
|
13
|
+
const rtmUserId = '2882341273'
|
|
14
|
+
const rtcTokenExpire = 600
|
|
15
|
+
const joinChannelPrivilegeExpire = 600
|
|
16
|
+
const pubAudioPrivilegeExpire = 600
|
|
17
|
+
const pubVideoPrivilegeExpire = 600
|
|
18
|
+
const pubDataStreamPrivilegeExpire = 600
|
|
19
|
+
const rtmTokenExpire = 600
|
|
20
|
+
|
|
21
|
+
exports.buildToken_PUBLISHER_Test = function (test) {
|
|
22
|
+
const token = ConvoAITokenBuilder.buildToken(
|
|
23
|
+
appId, appCertificate, channelName, rtcAccount, Role.PUBLISHER, rtcTokenExpire,
|
|
24
|
+
joinChannelPrivilegeExpire, pubAudioPrivilegeExpire, pubVideoPrivilegeExpire,
|
|
25
|
+
pubDataStreamPrivilegeExpire, rtmUserId, rtmTokenExpire)
|
|
26
|
+
const parsed = new AccessToken2('', '', 0, 0)
|
|
27
|
+
parsed.from_string(token)
|
|
28
|
+
|
|
29
|
+
const rtc = parsed.getServices(kRtcServiceType)[0]
|
|
30
|
+
const rtm = parsed.getServices(kRtmServiceType)[0]
|
|
31
|
+
const convoai = parsed.getServices(kConvoAIServiceType)[0]
|
|
32
|
+
|
|
33
|
+
test.equal(appId, parsed.appId)
|
|
34
|
+
test.equal(rtcTokenExpire, parsed.expire)
|
|
35
|
+
test.equal(channelName, rtc.__channel_name)
|
|
36
|
+
test.equal(rtcAccount, rtc.__uid)
|
|
37
|
+
test.equal(joinChannelPrivilegeExpire, rtc.__privileges[ServiceRtc.kPrivilegeJoinChannel])
|
|
38
|
+
test.equal(pubAudioPrivilegeExpire, rtc.__privileges[ServiceRtc.kPrivilegePublishAudioStream])
|
|
39
|
+
test.equal(pubVideoPrivilegeExpire, rtc.__privileges[ServiceRtc.kPrivilegePublishVideoStream])
|
|
40
|
+
test.equal(pubDataStreamPrivilegeExpire, rtc.__privileges[ServiceRtc.kPrivilegePublishDataStream])
|
|
41
|
+
test.equal(rtmUserId, rtm.__user_id)
|
|
42
|
+
test.equal(rtmTokenExpire, rtm.__privileges[ServiceRtm.kPrivilegeLogin])
|
|
43
|
+
test.deepEqual({}, convoai.__privileges)
|
|
44
|
+
test.done()
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
exports.buildToken_SUBSCRIBER_Test = function (test) {
|
|
48
|
+
const token = ConvoAITokenBuilder.buildToken(
|
|
49
|
+
appId, appCertificate, channelName, rtcAccount, Role.SUBSCRIBER, rtcTokenExpire,
|
|
50
|
+
joinChannelPrivilegeExpire, pubAudioPrivilegeExpire, pubVideoPrivilegeExpire,
|
|
51
|
+
pubDataStreamPrivilegeExpire, rtmUserId, rtmTokenExpire)
|
|
52
|
+
const parsed = new AccessToken2('', '', 0, 0)
|
|
53
|
+
parsed.from_string(token)
|
|
54
|
+
|
|
55
|
+
const rtc = parsed.getServices(kRtcServiceType)[0]
|
|
56
|
+
test.deepEqual({ [ServiceRtc.kPrivilegeJoinChannel]: joinChannelPrivilegeExpire }, rtc.__privileges)
|
|
57
|
+
test.done()
|
|
58
|
+
}
|
package/test/DynamicKeyTest.js
CHANGED
|
@@ -14,6 +14,7 @@ var r = 58964981;
|
|
|
14
14
|
var uid=2882341273;
|
|
15
15
|
var expiredTs=1446455471;
|
|
16
16
|
|
|
17
|
+
// Verifies deterministic public sharing key generation.
|
|
17
18
|
exports.PublicSharingKey5_Test = function(test) {
|
|
18
19
|
var expected = "005AwAoADc0QTk5RTVEQjI4MDk0NUI0NzUwNTk0MUFDMjM4MDU2NzIwREY3QjAQAJcMo13mDERkW7roohUGGzOwKDdW9buDA68oN1YAAA==";
|
|
19
20
|
var actual = DynamicKey5.generatePublicSharingKey(appID, appCertificate, channel, ts, r, uid, expiredTs);
|
|
@@ -21,6 +22,7 @@ exports.PublicSharingKey5_Test = function(test) {
|
|
|
21
22
|
test.done();
|
|
22
23
|
};
|
|
23
24
|
|
|
25
|
+
// Verifies deterministic recording key generation.
|
|
24
26
|
exports.RecordingKey5_Test = function(test) {
|
|
25
27
|
var expected = "005AgAoADkyOUM5RTQ2MTg3QTAyMkJBQUIyNkI3QkYwMTg0MzhDNjc1Q0ZFMUEQAJcMo13mDERkW7roohUGGzOwKDdW9buDA68oN1YAAA==";
|
|
26
28
|
var result = DynamicKey5.generateRecordingKey(appID, appCertificate, channel, ts, r, uid, expiredTs);
|
|
@@ -28,6 +30,7 @@ exports.RecordingKey5_Test = function(test) {
|
|
|
28
30
|
test.done();
|
|
29
31
|
};
|
|
30
32
|
|
|
33
|
+
// Verifies deterministic media channel key generation.
|
|
31
34
|
exports.MediaChannelKey5_Test = function(test) {
|
|
32
35
|
var expected = "005AQAoAEJERTJDRDdFNkZDNkU0ODYxNkYxQTYwOUVFNTM1M0U5ODNCQjFDNDQQAJcMo13mDERkW7roohUGGzOwKDdW9buDA68oN1YAAA==";
|
|
33
36
|
var result = DynamicKey5.generateMediaChannelKey(appID, appCertificate, channel, ts, r, uid, expiredTs);
|
|
@@ -35,6 +38,7 @@ exports.MediaChannelKey5_Test = function(test) {
|
|
|
35
38
|
test.done();
|
|
36
39
|
};
|
|
37
40
|
|
|
41
|
+
// Verifies deterministic in-channel permission key generation.
|
|
38
42
|
exports.InChannelPermission5_Test = function(test) {
|
|
39
43
|
var noUpload = "005BAAoADgyNEQxNDE4M0FGRDkyOEQ4REFFMUU1OTg5NTg2MzA3MTEyNjRGNzQQAJcMo13mDERkW7roohUGGzOwKDdW9buDA68oN1YBAAEAAQAw";
|
|
40
44
|
var generatedNoUpload = DynamicKey5.generateInChannelPermissionKey(appID, appCertificate, channel, ts, r, uid, expiredTs, DynamicKey5.noUpload);
|
|
@@ -12,18 +12,21 @@ const roomUuid = '123'
|
|
|
12
12
|
const userUuid = '2882341273'
|
|
13
13
|
const role = 1
|
|
14
14
|
|
|
15
|
+
// Verifies Education room-user token generation and parsing.
|
|
15
16
|
exports.BuildRoomUserToken_Test = function (test) {
|
|
16
17
|
let accessToken = new AccessToken2('', '', 0, 0)
|
|
17
18
|
let token = EducationTokenBuilder.buildRoomUserToken(appId, appCertificate, roomUuid, userUuid, role, expire)
|
|
18
19
|
accessToken.from_string(token)
|
|
20
|
+
const service = accessToken.getServices(kApaasServiceType)[0]
|
|
19
21
|
test.equal(appId, accessToken.appId)
|
|
20
22
|
test.equal(expire, accessToken.expire)
|
|
21
|
-
test.equal(roomUuid,
|
|
22
|
-
test.equal(userUuid,
|
|
23
|
-
test.equal(role,
|
|
23
|
+
test.equal(roomUuid, service.__room_uuid)
|
|
24
|
+
test.equal(userUuid, service.__user_uuid)
|
|
25
|
+
test.equal(role, service.__role)
|
|
24
26
|
test.done()
|
|
25
27
|
}
|
|
26
28
|
|
|
29
|
+
// Verifies Education user token generation and parsing.
|
|
27
30
|
exports.BuildUserToken_Test = function (test) {
|
|
28
31
|
let accessToken = new AccessToken2('', '', 0, 0)
|
|
29
32
|
let token = EducationTokenBuilder.buildUserToken(appId, appCertificate, userUuid, expire)
|
|
@@ -31,10 +34,11 @@ exports.BuildUserToken_Test = function (test) {
|
|
|
31
34
|
|
|
32
35
|
test.equal(appId, accessToken.appId)
|
|
33
36
|
test.equal(expire, accessToken.expire)
|
|
34
|
-
test.equal(userUuid, accessToken.
|
|
37
|
+
test.equal(userUuid, accessToken.getServices(kApaasServiceType)[0].__user_uuid)
|
|
35
38
|
test.done()
|
|
36
39
|
}
|
|
37
40
|
|
|
41
|
+
// Verifies Education application token generation and parsing.
|
|
38
42
|
exports.BuildAppToken_Test = function (test) {
|
|
39
43
|
let accessToken = new AccessToken2('', '', 0, 0)
|
|
40
44
|
let token = EducationTokenBuilder.buildAppToken(appId, appCertificate, expire)
|