agora-token 2.0.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.
@@ -0,0 +1,414 @@
1
+ var crypto = require('crypto')
2
+ const zlib = require('zlib')
3
+ const VERSION_LENGTH = 3
4
+ const APP_ID_LENGTH = 32
5
+
6
+ const getVersion = () => {
7
+ return "007"
8
+ }
9
+
10
+ class Service {
11
+ constructor(service_type) {
12
+ this.__type = service_type
13
+ this.__privileges = {}
14
+ }
15
+
16
+ __pack_type() {
17
+ let buf = new ByteBuf()
18
+ buf.putUint16(this.__type)
19
+ return buf.pack()
20
+ }
21
+
22
+ __pack_privileges() {
23
+ let buf = new ByteBuf()
24
+ buf.putTreeMapUInt32(this.__privileges)
25
+ return buf.pack()
26
+ }
27
+
28
+ service_type() {
29
+ return this.__type
30
+ }
31
+
32
+ add_privilege(privilege, expire) {
33
+ this.__privileges[privilege] = expire
34
+ }
35
+
36
+ pack() {
37
+ return Buffer.concat([this.__pack_type(), this.__pack_privileges()])
38
+ }
39
+
40
+ unpack(buffer) {
41
+ let bufReader = new ReadByteBuf(buffer)
42
+ this.__privileges = bufReader.getTreeMapUInt32()
43
+ return bufReader
44
+ }
45
+ }
46
+
47
+ const kRtcServiceType = 1
48
+
49
+ class ServiceRtc extends Service {
50
+ constructor(channel_name, uid) {
51
+ super(kRtcServiceType)
52
+ this.__channel_name = channel_name
53
+ this.__uid = uid === 0 ? '' : `${uid}`
54
+ }
55
+
56
+ pack() {
57
+ let buffer = new ByteBuf()
58
+ buffer.putString(this.__channel_name).putString(this.__uid)
59
+ return Buffer.concat([super.pack(), buffer.pack()])
60
+ }
61
+
62
+ unpack(buffer) {
63
+ let bufReader = super.unpack(buffer)
64
+ this.__channel_name = bufReader.getString()
65
+ this.__uid = bufReader.getString()
66
+ return bufReader
67
+ }
68
+ }
69
+
70
+ ServiceRtc.kPrivilegeJoinChannel = 1
71
+ ServiceRtc.kPrivilegePublishAudioStream = 2
72
+ ServiceRtc.kPrivilegePublishVideoStream = 3
73
+ ServiceRtc.kPrivilegePublishDataStream = 4
74
+
75
+ const kRtmServiceType = 2
76
+
77
+ class ServiceRtm extends Service {
78
+ constructor(user_id) {
79
+ super(kRtmServiceType)
80
+ this.__user_id = user_id || ""
81
+ }
82
+
83
+ pack() {
84
+ let buffer = new ByteBuf()
85
+ buffer.putString(this.__user_id)
86
+ return Buffer.concat([super.pack(), buffer.pack()])
87
+ }
88
+
89
+ unpack(buffer) {
90
+ let bufReader = super.unpack(buffer)
91
+ this.__user_id = bufReader.getString()
92
+ return bufReader
93
+ }
94
+ }
95
+
96
+ ServiceRtm.kPrivilegeLogin = 1
97
+
98
+
99
+ const kFpaServiceType = 4
100
+
101
+ class ServiceFpa extends Service {
102
+ constructor() {
103
+ super(kFpaServiceType)
104
+ }
105
+
106
+ pack() {
107
+ return super.pack()
108
+ }
109
+
110
+ unpack(buffer) {
111
+ let bufReader = super.unpack(buffer)
112
+ return bufReader
113
+ }
114
+ }
115
+
116
+ ServiceFpa.kPrivilegeLogin = 1
117
+
118
+
119
+ const kChatServiceType = 5
120
+
121
+ class ServiceChat extends Service {
122
+ constructor(user_id) {
123
+ super(kChatServiceType)
124
+ this.__user_id = user_id || ""
125
+ }
126
+
127
+ pack() {
128
+ let buffer = new ByteBuf()
129
+ buffer.putString(this.__user_id)
130
+ return Buffer.concat([super.pack(), buffer.pack()])
131
+ }
132
+
133
+ unpack(buffer) {
134
+ let bufReader = super.unpack(buffer)
135
+ this.__user_id = bufReader.getString()
136
+ return bufReader
137
+ }
138
+ }
139
+
140
+ ServiceChat.kPrivilegeUser = 1
141
+ ServiceChat.kPrivilegeApp = 2
142
+
143
+ const kEducationServiceType = 7
144
+
145
+ class ServiceEducation extends Service {
146
+ constructor(roomUuid, userUuid, role) {
147
+ super(kEducationServiceType)
148
+ this.__room_uuid = roomUuid || ""
149
+ this.__user_uuid = userUuid || ""
150
+ this.__role = role || -1
151
+ }
152
+
153
+ pack() {
154
+ let buffer = new ByteBuf()
155
+ buffer.putString(this.__room_uuid)
156
+ buffer.putString(this.__user_uuid)
157
+ buffer.putInt16(this.__role)
158
+ return Buffer.concat([super.pack(), buffer.pack()])
159
+ }
160
+
161
+ unpack(buffer) {
162
+ let bufReader = super.unpack(buffer)
163
+ this.__room_uuid = bufReader.getString()
164
+ this.__user_uuid = bufReader.getString()
165
+ this.__role = bufReader.getInt16()
166
+ return bufReader
167
+ }
168
+ }
169
+
170
+ ServiceEducation.PRIVILEGE_ROOM_USER = 1
171
+ ServiceEducation.PRIVILEGE_USER = 2
172
+ ServiceEducation.PRIVILEGE_APP = 3
173
+
174
+
175
+ class AccessToken2 {
176
+ constructor(appId, appCertificate, issueTs, expire) {
177
+ this.appId = appId
178
+ this.appCertificate = appCertificate
179
+ this.issueTs = issueTs || new Date().getTime() / 1000
180
+ this.expire = expire
181
+ // salt ranges in (1, 99999999)
182
+ this.salt = Math.floor(Math.random() * (99999999)) + 1
183
+ this.services = {}
184
+ }
185
+
186
+ __signing() {
187
+ let signing = encodeHMac(new ByteBuf().putUint32(this.issueTs).pack(), this.appCertificate)
188
+ signing = encodeHMac(new ByteBuf().putUint32(this.salt).pack(), signing)
189
+ return signing
190
+ }
191
+
192
+ __build_check() {
193
+ let is_uuid = (data) => {
194
+ if (data.length !== APP_ID_LENGTH) {
195
+ return false
196
+ }
197
+ let buf = Buffer.from(data, 'hex')
198
+ return !!buf
199
+ }
200
+
201
+ const {appId, appCertificate, services} = this
202
+ if (!is_uuid(appId) || !is_uuid(appCertificate)) {
203
+ return false
204
+ }
205
+
206
+ if (Object.keys(services).length === 0) {
207
+ return false
208
+ }
209
+ return true
210
+ }
211
+
212
+ add_service(service) {
213
+ this.services[service.service_type()] = service
214
+ }
215
+
216
+ build() {
217
+ if (!this.__build_check()) {
218
+ return ""
219
+ }
220
+
221
+ let signing = this.__signing()
222
+ let signing_info = new ByteBuf().putString(this.appId)
223
+ .putUint32(this.issueTs)
224
+ .putUint32(this.expire)
225
+ .putUint32(this.salt)
226
+ .putUint16(Object.keys(this.services).length).pack()
227
+ Object.values(this.services).forEach(service => {
228
+ signing_info = Buffer.concat([signing_info, service.pack()])
229
+ })
230
+
231
+ let signature = encodeHMac(signing, signing_info)
232
+ let content = Buffer.concat([new ByteBuf().putString(signature).pack(), signing_info])
233
+ let compressed = zlib.deflateSync(content)
234
+ return `${getVersion()}${Buffer.from(compressed).toString('base64')}`
235
+ }
236
+
237
+ from_string(origin_token) {
238
+ let origin_version = origin_token.substring(0, VERSION_LENGTH)
239
+ if (origin_version !== getVersion()) {
240
+ return false
241
+ }
242
+
243
+ let origin_content = origin_token.substring(VERSION_LENGTH, origin_token.length)
244
+ let buffer = zlib.inflateSync(new Buffer(origin_content, 'base64'))
245
+ let bufferReader = new ReadByteBuf(buffer)
246
+
247
+ let signature = bufferReader.getString()
248
+ this.appId = bufferReader.getString()
249
+ this.issueTs = bufferReader.getUint32()
250
+ this.expire = bufferReader.getUint32()
251
+ this.salt = bufferReader.getUint32()
252
+ let service_count = bufferReader.getUint16()
253
+
254
+ let remainBuf = bufferReader.pack()
255
+ for (let i = 0; i < service_count; i++) {
256
+ let bufferReaderService = new ReadByteBuf(remainBuf)
257
+ let service_type = bufferReaderService.getUint16()
258
+ let service = new AccessToken2.kServices[service_type]()
259
+ remainBuf = service.unpack(bufferReaderService.pack()).pack()
260
+ this.services[service_type] = service
261
+ }
262
+ }
263
+ }
264
+
265
+ var encodeHMac = function (key, message) {
266
+ return crypto.createHmac('sha256', key).update(message).digest()
267
+ }
268
+
269
+ var ByteBuf = function () {
270
+ var that = {
271
+ buffer: Buffer.alloc(1024)
272
+ , position: 0
273
+ }
274
+
275
+ that.buffer.fill(0)
276
+
277
+ that.pack = function () {
278
+ var out = Buffer.alloc(that.position)
279
+ that.buffer.copy(out, 0, 0, out.length)
280
+ return out
281
+ }
282
+
283
+ that.putUint16 = function (v) {
284
+ that.buffer.writeUInt16LE(v, that.position)
285
+ that.position += 2
286
+ return that
287
+ }
288
+
289
+ that.putUint32 = function (v) {
290
+ that.buffer.writeUInt32LE(v, that.position)
291
+ that.position += 4
292
+ return that
293
+ }
294
+ that.putInt32 = function (v) {
295
+ that.buffer.writeInt32LE(v, that.position)
296
+ that.position += 4
297
+ return that
298
+ }
299
+
300
+ that.putInt16 = function (v) {
301
+ that.buffer.writeInt16LE(v, that.position)
302
+ that.position += 2
303
+ return that
304
+ }
305
+
306
+ that.putBytes = function (bytes) {
307
+ that.putUint16(bytes.length)
308
+ bytes.copy(that.buffer, that.position)
309
+ that.position += bytes.length
310
+ return that
311
+ }
312
+
313
+ that.putString = function (str) {
314
+ return that.putBytes(Buffer.from(str))
315
+ }
316
+
317
+ that.putTreeMap = function (map) {
318
+ if (!map) {
319
+ that.putUint16(0)
320
+ return that
321
+ }
322
+
323
+ that.putUint16(Object.keys(map).length)
324
+ for (var key in map) {
325
+ that.putUint16(key)
326
+ that.putString(map[key])
327
+ }
328
+
329
+ return that
330
+ }
331
+
332
+ that.putTreeMapUInt32 = function (map) {
333
+ if (!map) {
334
+ that.putUint16(0)
335
+ return that
336
+ }
337
+
338
+ that.putUint16(Object.keys(map).length)
339
+ for (var key in map) {
340
+ that.putUint16(key)
341
+ that.putUint32(map[key])
342
+ }
343
+
344
+ return that
345
+ }
346
+
347
+ return that
348
+ }
349
+
350
+ var ReadByteBuf = function (bytes) {
351
+ var that = {
352
+ buffer: bytes
353
+ , position: 0
354
+ }
355
+
356
+ that.getUint16 = function () {
357
+ var ret = that.buffer.readUInt16LE(that.position)
358
+ that.position += 2
359
+ return ret
360
+ }
361
+
362
+ that.getUint32 = function () {
363
+ var ret = that.buffer.readUInt32LE(that.position)
364
+ that.position += 4
365
+ return ret
366
+ }
367
+
368
+ that.getInt16 = function () {
369
+ var ret = that.buffer.readUInt16LE(that.position)
370
+ that.position += 2
371
+ return ret
372
+ }
373
+
374
+ that.getString = function () {
375
+ var len = that.getUint16()
376
+
377
+ var out = Buffer.alloc(len)
378
+ that.buffer.copy(out, 0, that.position, (that.position + len))
379
+ that.position += len
380
+ return out
381
+ }
382
+
383
+ that.getTreeMapUInt32 = function () {
384
+ var map = {}
385
+ var len = that.getUint16()
386
+ for (var i = 0; i < len; i++) {
387
+ var key = that.getUint16()
388
+ var value = that.getUint32()
389
+ map[key] = value
390
+ }
391
+ return map
392
+ }
393
+
394
+ that.pack = function () {
395
+ let length = that.buffer.length
396
+ var out = Buffer.alloc(length)
397
+ that.buffer.copy(out, 0, that.position, length)
398
+ return out
399
+ }
400
+
401
+ return that
402
+ }
403
+
404
+ AccessToken2.kServices = {}
405
+ AccessToken2.kServices[kRtcServiceType] = ServiceRtc
406
+ AccessToken2.kServices[kRtmServiceType] = ServiceRtm
407
+ AccessToken2.kServices[kFpaServiceType] = ServiceFpa
408
+ AccessToken2.kServices[kChatServiceType] = ServiceChat
409
+ AccessToken2.kServices[kEducationServiceType] = ServiceEducation
410
+
411
+ module.exports = {
412
+ AccessToken2, ServiceRtc, ServiceRtm, ServiceFpa, ServiceChat, ServiceEducation,
413
+ kRtcServiceType, kRtmServiceType, kFpaServiceType, kChatServiceType, kEducationServiceType,
414
+ }
@@ -0,0 +1,173 @@
1
+ var crypto = require('crypto');
2
+
3
+ var version = "005";
4
+ var noUpload = "0";
5
+ var audioVideoUpload = "3";
6
+
7
+ var generatePublicSharingKey = function (appID, appCertificate, channelName, unixTs, randomInt, uid, expiredTs) {
8
+ channelName=channelName.toString();
9
+ return generateDynamicKey(appID, appCertificate, channelName, unixTs, randomInt, uid, expiredTs, null, PUBLIC_SHARING_SERVICE);
10
+ };
11
+
12
+ var generateRecordingKey = function (appID, appCertificate, channelName, unixTs, randomInt, uid, expiredTs) {
13
+ channelName=channelName.toString();
14
+ return generateDynamicKey(appID, appCertificate, channelName, unixTs, randomInt, uid, expiredTs, null, RECORDING_SERVICE);
15
+ };
16
+
17
+ var generateMediaChannelKey = function (appID, appCertificate, channelName, unixTs, randomInt, uid, expiredTs) {
18
+ channelName=channelName.toString();
19
+ return generateDynamicKey(appID, appCertificate, channelName, unixTs, randomInt, uid, expiredTs, null, MEDIA_CHANNEL_SERVICE);
20
+ };
21
+
22
+ var generateInChannelPermissionKey = function (appID, appCertificate, channelName, unixTs, randomInt, uid, expiredTs, permission) {
23
+ var extra = {};
24
+ extra[ALLOW_UPLOAD_IN_CHANNEL] = permission;
25
+ return generateDynamicKey(appID, appCertificate, channelName, unixTs, randomInt, uid, expiredTs, extra, IN_CHANNEL_PERMISSION);
26
+ };
27
+
28
+ var generateDynamicKey = function (appID, appCertificate, channelName, unixTs, randomInt, uid, expiredTs, extra, serviceType) {
29
+ var signature = generateSignature5(appCertificate, serviceType, appID, unixTs, randomInt, channelName, uid, expiredTs, extra);
30
+ var content = DynamicKey5Content({
31
+ serviceType: serviceType
32
+ , signature: signature
33
+ , appID: hexDecode(appID)
34
+ , unixTs: unixTs
35
+ , salt: randomInt
36
+ , expiredTs: expiredTs
37
+ , extra: extra}).pack();
38
+ return version + content.toString('base64');
39
+ };
40
+
41
+ module.exports.version = version;
42
+ module.exports.noUpload = noUpload;
43
+ module.exports.audioVideoUpload = audioVideoUpload;
44
+ module.exports.generatePublicSharingKey = generatePublicSharingKey;
45
+ module.exports.generateRecordingKey = generateRecordingKey;
46
+ module.exports.generateMediaChannelKey = generateMediaChannelKey;
47
+ module.exports.generateInChannelPermissionKey = generateInChannelPermissionKey;
48
+ module.exports.generateDynamicKey = generateDynamicKey;
49
+
50
+ var generateSignature5 = function(appCertificate, serviceType, appID, unixTs, randomInt, channelName, uid, expiredTs, extra) {
51
+ // decode hex to avoid case problem
52
+ var rawAppID = hexDecode(appID);
53
+ var rawAppCertificate = hexDecode(appCertificate);
54
+
55
+ var m = Message({
56
+ serviceType: serviceType
57
+ , appID: rawAppID
58
+ , unixTs: unixTs
59
+ , salt: randomInt
60
+ , channelName: channelName
61
+ , uid: uid
62
+ , expiredTs: expiredTs
63
+ , extra: extra
64
+ });
65
+
66
+ var toSign = m.pack();
67
+ return encodeHMac(rawAppCertificate, toSign);
68
+ };
69
+
70
+ var encodeHMac = function(key, message) {
71
+ return crypto.createHmac('sha1', key).update(message).digest('hex').toUpperCase();
72
+ };
73
+
74
+ var hexDecode = function(str) {
75
+ return Buffer.from(str, 'hex');
76
+ };
77
+
78
+ var ByteBuf = function() {
79
+ var that = {
80
+ buffer: Buffer.alloc(1024)
81
+ , position: 0
82
+ };
83
+
84
+ that.buffer.fill(0);
85
+
86
+ that.pack = function() {
87
+ var out = Buffer.alloc(that.position);
88
+ that.buffer.copy(out, 0, 0, out.length);
89
+ return out;
90
+ };
91
+
92
+ that.putUint16 = function(v) {
93
+ that.buffer.writeUInt16LE(v, that.position);
94
+ that.position += 2;
95
+ return that;
96
+ };
97
+
98
+ that.putUint32 = function(v) {
99
+ that.buffer.writeUInt32LE(v, that.position);
100
+ that.position += 4;
101
+ return that;
102
+ };
103
+
104
+ that.putBytes = function(bytes) {
105
+ that.putUint16(bytes.length);
106
+ bytes.copy(that.buffer, that.position);
107
+ that.position += bytes.length;
108
+ return that;
109
+ };
110
+
111
+ that.putString = function(str) {
112
+ return that.putBytes(Buffer.from(str));
113
+ };
114
+
115
+ that.putTreeMap = function(map) {
116
+ if (!map) {
117
+ that.putUint16(0);
118
+ return that;
119
+ }
120
+
121
+ that.putUint16(Object.keys(map).length);
122
+ for (var key in map) {
123
+ that.putUint16(key);
124
+ that.putString(map[key]);
125
+ }
126
+
127
+ return that;
128
+ };
129
+
130
+ return that;
131
+ }
132
+
133
+ var DynamicKey5Content = function(options) {
134
+ options.pack = function() {
135
+ var out = ByteBuf();
136
+ return out.putUint16(options.serviceType)
137
+ .putString(options.signature)
138
+ .putBytes(options.appID)
139
+ .putUint32(options.unixTs)
140
+ .putUint32(options.salt)
141
+ .putUint32(options.expiredTs)
142
+ .putTreeMap(options.extra)
143
+ .pack();
144
+ }
145
+
146
+ return options;
147
+ }
148
+
149
+ var Message = function(options) {
150
+ options.pack = function() {
151
+ var out = ByteBuf();
152
+ return out.putUint16(options.serviceType)
153
+ .putBytes(options.appID)
154
+ .putUint32(options.unixTs)
155
+ .putUint32(options.salt)
156
+ .putString(options.channelName)
157
+ .putUint32(options.uid)
158
+ .putUint32(options.expiredTs)
159
+ .putTreeMap(options.extra)
160
+ .pack();
161
+ }
162
+
163
+ return options;
164
+ }
165
+
166
+ // InChannelPermissionKey
167
+ var ALLOW_UPLOAD_IN_CHANNEL = 1;
168
+
169
+ // Service Type
170
+ var MEDIA_CHANNEL_SERVICE = 1;
171
+ var RECORDING_SERVICE = 2;
172
+ var PUBLIC_SHARING_SERVICE = 3;
173
+ var IN_CHANNEL_PERMISSION = 4;
@@ -0,0 +1,80 @@
1
+ const AccessToken = require('../src/AccessToken2').AccessToken2
2
+ const ServiceEducation = require('../src/AccessToken2').ServiceEducation
3
+ const ServiceRtm = require('../src/AccessToken2').ServiceRtm
4
+ const ServiceChat = require('../src/AccessToken2').ServiceChat
5
+ const md5 = require("md5")
6
+
7
+
8
+ class EducationTokenBuilder {
9
+ /**
10
+ * build user room token
11
+ * @param appId The App ID issued to you by Agora. Apply for a new App ID from
12
+ * Agora Dashboard if it is missing from your kit. See Get an App ID.
13
+ * @param appCertificate Certificate of the application that you registered in
14
+ * the Agora Dashboard. See Get an App Certificate.
15
+ * @param roomUuid The room's id, must be unique.
16
+ * @param userUuid The user's id, must be unique.
17
+ * @param role The user's role, such as 0(invisible), 1(teacher), 2(student), 3(assistant), 4(observer) etc.
18
+ * @param expire represented by the number of seconds elapsed since now. If, for example, you want to access the
19
+ * Agora Service within 10 minutes after the token is generated, set expireTimestamp as 600(seconds).
20
+ * @return The education user room token.
21
+ */
22
+ static buildRoomUserToken(appId, appCertificate, roomUuid, userUuid, role, expire) {
23
+ let accessToken = new AccessToken(appId, appCertificate, 0, expire)
24
+
25
+ let chatUserId = md5(userUuid)
26
+ let eduService = new ServiceEducation(roomUuid, userUuid, role)
27
+ accessToken.add_service(eduService)
28
+
29
+ let rtmService = new ServiceRtm(userUuid)
30
+ rtmService.add_privilege(ServiceRtm.kPrivilegeLogin, expire)
31
+ accessToken.add_service(rtmService)
32
+
33
+ let chatService = new ServiceChat(chatUserId)
34
+ chatService.add_privilege(ServiceChat.kPrivilegeUser, expire)
35
+ accessToken.add_service(chatService)
36
+
37
+ return accessToken.build()
38
+ }
39
+
40
+ /**
41
+ * build user individual token
42
+ * @param appId The App ID issued to you by Agora. Apply for a new App ID from
43
+ * Agora Dashboard if it is missing from your kit. See Get an App ID.
44
+ * @param appCertificate Certificate of the application that you registered in
45
+ * the Agora Dashboard. See Get an App Certificate.
46
+ * @param userUuid The user's id, must be unique.
47
+ * @param expire represented by the number of seconds elapsed since now. If, for example, you want to access the
48
+ * Agora Service within 10 minutes after the token is generated, set expireTimestamp as 600(seconds).
49
+ * @return The education user token.
50
+ */
51
+ static buildUserToken(appId, appCertificate, userUuid, expire) {
52
+ let accessToken = new AccessToken(appId, appCertificate, 0, expire)
53
+ let eduService = new ServiceEducation("", userUuid)
54
+ eduService.add_privilege(ServiceEducation.PRIVILEGE_USER, expire)
55
+ accessToken.add_service(eduService)
56
+
57
+ return accessToken.build()
58
+ }
59
+
60
+ /**
61
+ * build app global token
62
+ * @param appId The App ID issued to you by Agora. Apply for a new App ID from
63
+ * Agora Dashboard if it is missing from your kit. See Get an App ID.
64
+ * @param appCertificate Certificate of the application that you registered in
65
+ * the Agora Dashboard. See Get an App Certificate.
66
+ * @param expire represented by the number of seconds elapsed since now. If, for example, you want to access the
67
+ * Agora Service within 10 minutes after the token is generated, set expireTimestamp as 600(seconds).
68
+ * @return The education global token.
69
+ */
70
+ static buildAppToken(appId, appCertificate, expire) {
71
+ let accessToken = new AccessToken(appId, appCertificate, 0, expire)
72
+ let eduService = new ServiceEducation()
73
+ eduService.add_privilege(ServiceEducation.PRIVILEGE_APP, expire)
74
+ accessToken.add_service(eduService)
75
+
76
+ return accessToken.build()
77
+ }
78
+ }
79
+
80
+ module.exports.EducationTokenBuilder = EducationTokenBuilder
@@ -0,0 +1,24 @@
1
+ const AccessToken = require('../src/AccessToken2').AccessToken2
2
+ const ServiceFpa = require('../src/AccessToken2').ServiceFpa
3
+
4
+ class FpaTokenBuilder {
5
+ /**
6
+ * Build the FPA token.
7
+ * @param appId The App ID issued to you by Agora. Apply for a new App ID from
8
+ * Agora Dashboard if it is missing from your kit. See Get an App ID.
9
+ * @param appCertificate Certificate of the application that you registered in
10
+ * the Agora Dashboard. See Get an App Certificate.
11
+ * @return The FPA token.
12
+ */
13
+ static buildToken(appId, appCertificate) {
14
+ let token = new AccessToken(appId, appCertificate, 0, 24 * 3600)
15
+
16
+ let serviceFpa = new ServiceFpa()
17
+ serviceFpa.add_privilege(ServiceFpa.kPrivilegeLogin, 0)
18
+ token.add_service(serviceFpa)
19
+
20
+ return token.build()
21
+ }
22
+ }
23
+
24
+ module.exports.FpaTokenBuilder = FpaTokenBuilder