@arcblock/did-connect-js 1.21.2

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,168 @@
1
+ /* eslint-disable object-curly-newline */
2
+ // eslint-disable-next-line
3
+ const debug = require('debug')(`${require('../../package.json').name}:handlers:wallet`);
4
+
5
+ const cors = require('cors');
6
+
7
+ const createHandlers = require('./util');
8
+ const BaseHandler = require('./base');
9
+
10
+ const noop = () => {};
11
+
12
+ /**
13
+ * Events that are emitted during an DID Connect process
14
+ *
15
+ * - scanned: when the qrcode is scanned by wallet
16
+ * - succeed: when authentication complete
17
+ * - error: when something goes wrong
18
+ *
19
+ * @class WalletHandlers
20
+ * @extends {EventEmitter}
21
+ */
22
+ class WalletHandlers extends BaseHandler {
23
+ /**
24
+ * Creates an instance of DID Auth Handlers.
25
+ *
26
+ * @class
27
+ * @param {object} config
28
+ * @param {object} config.tokenStorage - function to generate action token
29
+ * @param {object} config.authenticator - Authenticator instance that can to jwt sign/verify
30
+ * @param {function} [config.pathTransformer=null] - how should we update pathname
31
+ * @param {function} [config.onConnect=noop] - function called before each auth request send back to app, used to check for permission, throw error to halt the auth process
32
+ * @param {object} [config.options={}] - custom options to define all handlers attached
33
+ * @param {string} [config.options.prefix='/api/did'] - url prefix for this group endpoints
34
+ * @param {number} [config.options.cleanupDelay=60000] - how long to wait before cleanup finished session
35
+ * @param {string} [config.options.tokenKey='_t_'] - query param key for `token`
36
+ * @param {string} [config.options.encKey='_ek_'] - query param key for encryption key
37
+ * @param {string} [config.options.versionKey='_v_'] - query param key for protocol `version`
38
+ */
39
+ constructor({ pathTransformer, tokenStorage, authenticator, onConnect = noop, options = {} }) {
40
+ super({ pathTransformer, tokenStorage, authenticator, onConnect });
41
+
42
+ this.options = {
43
+ prefix: '/api/did',
44
+ cleanupDelay: 60000,
45
+ tokenKey: '_t_',
46
+ encKey: '_ek_',
47
+ versionKey: '_v_',
48
+ ...options,
49
+ };
50
+ }
51
+
52
+ /**
53
+ * Attach routes and handlers for authenticator
54
+ * Now express app have route handlers attached to the following url
55
+ * - `GET /api/did/{action}/token` create new token
56
+ * - `GET /api/did/{action}/status` check for token status
57
+ * - `GET /api/did/{action}/timeout` expire a token
58
+ * - `GET /api/did/{action}/auth` create auth response
59
+ * - `POST /api/did/{action}/auth` process payment request
60
+ *
61
+ * @method
62
+ * @param {object} config
63
+ * @param {object} config.app - express instance to attach routes to
64
+ * @param {object} [config.claims] - claims for this request
65
+ * @param {string} config.action - action of this group of routes
66
+ * @param {function} [config.onStart=noop] - callback when a new action start
67
+ * @param {function} [config.onConnect=noop] - callback when a new action start
68
+ * @param {function} config.onAuth - callback when user completed auth in DID Wallet, and data posted back
69
+ * @param {function} [config.onDecline=noop] - callback when user has declined in wallet
70
+ * @param {function} [config.onComplete=noop] - callback when the whole auth process is done, action token is removed
71
+ * @param {function} [config.onExpire=noop] - callback when the action token expired
72
+ * @param {function} [config.onError=console.error] - callback when there are some errors
73
+ * @param {boolean|string|did} [config.authPrincipal=true] - whether should we do auth principal claim first
74
+ * @param {boolean} [config.persistentDynamicClaims=false] - whether should we persist dynamic claims
75
+ * @return void
76
+ */
77
+ attach({
78
+ app,
79
+ action,
80
+ claims = undefined,
81
+ onStart = noop,
82
+ onConnect,
83
+ onAuth,
84
+ onDecline = noop,
85
+ onComplete = noop,
86
+ onExpire = noop,
87
+ // eslint-disable-next-line no-console
88
+ onError = console.error,
89
+ authPrincipal = true,
90
+ persistentDynamicClaims = false,
91
+ }) {
92
+ if (typeof onAuth !== 'function') {
93
+ throw new Error('onAuth callback is required to attach did auth handlers');
94
+ }
95
+ if (typeof onDecline !== 'function') {
96
+ throw new Error('onDecline callback is required to attach did auth handlers');
97
+ }
98
+ if (typeof onComplete !== 'function') {
99
+ throw new Error('onComplete callback is required to attach did auth handlers');
100
+ }
101
+
102
+ const { prefix } = this.options;
103
+
104
+ // pathname for DID Wallet, which will be included for authenticator signing
105
+ const pathname = `${prefix}/${action}/auth`;
106
+ debug('attach routes', { action, prefix, pathname });
107
+
108
+ // eslint-disable-next-line consistent-return
109
+ const onConnectWrapped = async (...args) => {
110
+ if (typeof this.onConnect === 'function') {
111
+ await this.onConnect(...args);
112
+ }
113
+ if (typeof onConnect === 'function') {
114
+ return onConnect(...args);
115
+ }
116
+ };
117
+
118
+ const {
119
+ generateSession,
120
+ expireSession,
121
+ checkSession,
122
+ onAuthRequest,
123
+ onAuthResponse,
124
+ ensureContext,
125
+ ensureSignedJson,
126
+ } = createHandlers({
127
+ action,
128
+ pathname,
129
+ claims,
130
+ onStart,
131
+ onConnect: onConnectWrapped, // must be deterministic when returning dynamic claims
132
+ onAuth,
133
+ onDecline,
134
+ onComplete,
135
+ onExpire,
136
+ onError,
137
+ authPrincipal,
138
+ persistentDynamicClaims,
139
+ options: this.options,
140
+ pathTransformer: this.pathTransformer,
141
+ tokenStorage: this.tokenStorage,
142
+ authenticator: this.authenticator,
143
+ });
144
+
145
+ app.use(`${prefix}/${action}`, cors({ origin: '*', optionsSuccessStatus: 204 }));
146
+
147
+ // 1. WEB|Wallet: to generate new token
148
+ app.get(`${prefix}/${action}/token`, generateSession);
149
+ app.post(`${prefix}/${action}/token`, generateSession);
150
+
151
+ // 2. WEB: check for token status
152
+ app.get(`${prefix}/${action}/status`, ensureContext, checkSession);
153
+
154
+ // 3. WEB: to expire old token
155
+ app.get(`${prefix}/${action}/timeout`, ensureContext, expireSession);
156
+
157
+ // 4. Wallet: fetch auth request
158
+ app.get(pathname, ensureContext, ensureSignedJson, onAuthRequest);
159
+
160
+ // 5. Wallet: submit auth response
161
+ app.post(pathname, ensureContext, ensureSignedJson, onAuthResponse);
162
+
163
+ // 6. Wallet: submit auth response for web wallet
164
+ app.get(`${pathname}/submit`, ensureContext, ensureSignedJson, onAuthResponse);
165
+ }
166
+ }
167
+
168
+ module.exports = WalletHandlers;
package/lib/index.d.ts ADDED
@@ -0,0 +1,384 @@
1
+ // Generate by [js2dts@0.3.3](https://github.com/whxaxes/js2dts#readme)
2
+
3
+ import * as events from 'events';
4
+ declare class BaseAuthenticator {}
5
+ declare class WalletAuthenticator extends BaseAuthenticator {
6
+ wallet: any;
7
+ appInfo: any;
8
+ memberAppInfo: any;
9
+ chainInfo: any;
10
+ delegator: any;
11
+ delegation: any;
12
+ baseUrl: any;
13
+ tokenKey: any;
14
+ timeout: any;
15
+ /**
16
+ * @typedef ApplicationInfo
17
+ * @prop {string} name - application name
18
+ * @prop {string} description - application description
19
+ * @prop {string} icon - application icon/logo url
20
+ * @prop {string} link - application home page, with which user can return application from wallet
21
+ * @prop {string} path - deep link url
22
+ * @prop {string} publisher - application did with `did:abt:` prefix
23
+ */
24
+
25
+ /**
26
+ * @typedef ChainInfo
27
+ * @prop {string} id - application chain id
28
+ * @prop {string} type - application chain type
29
+ * @prop {string} host - graphql endpoint of the application chain
30
+ */
31
+
32
+ /**
33
+ * Creates an instance of DID Authenticator.
34
+ *
35
+ * @class
36
+ * @param {object} config
37
+ * @param {WalletObject|Function} config.wallet - wallet instance {@see @ocap/wallet} or a function that returns wallet instance
38
+ * @param {WalletObject|Function} [config.delegator] - the party that authorizes `wallet` to perform actions on behalf of `wallet`
39
+ * @param {string|Function} [config.delegation] - the jwt token that proves delegation relationship
40
+ * @param {ApplicationInfo|Function} config.appInfo - application basic info or a function that returns application info
41
+ * @param {ChainInfo|Function} config.chainInfo - application chain info or a function that returns chain info
42
+ * @param {Number} [config.timeout=8000] - timeout in milliseconds when generating claim
43
+ * @param {object} [config.baseUrl] - url to assemble wallet request uri, can be inferred from request object
44
+ * @param {string} [config.tokenKey='_t_'] - query param key for `token`
45
+ * @example
46
+ * const { fromRandom } = require('@ocap/wallet');
47
+ *
48
+ * const wallet = fromRandom().toJSON();
49
+ * const chainHost = 'https://beta.abtnetwork.io/api';
50
+ * const chainId = 'beta';
51
+ * const auth = new Authenticator({
52
+ * wallet,
53
+ * baseUrl: 'http://beta.abtnetwork.io/webapp',
54
+ * appInfo: {
55
+ * name: 'DID Wallet Demo',
56
+ * description: 'Demo application to show the potential of DID Wallet',
57
+ * icon: 'https://arcblock.oss-cn-beijing.aliyuncs.com/images/wallet-round.png',
58
+ * },
59
+ * memberAppInfo: null,
60
+ * chainInfo: {
61
+ * host: chainHost,
62
+ * id: chainId,
63
+ * },
64
+ * timeout: 8000,
65
+ * });
66
+ */
67
+ constructor(T100: _Lib.T101);
68
+ /**
69
+ * Generate a deep link url that can be displayed as QRCode for DID Wallet to consume
70
+ *
71
+ * @method
72
+ * @param {object} params
73
+ * @param {string} params.baseUrl - baseUrl inferred from request object
74
+ * @param {string} params.pathname - wallet callback pathname
75
+ * @param {string} params.token - action token
76
+ * @param {object} params.query - params that should be persisted in wallet callback url
77
+ * @returns {string}
78
+ */
79
+ uri(T102?: _Lib.T103): string;
80
+ /**
81
+ * Compute public url to return to wallet
82
+ *
83
+ * @method
84
+ * @param {string} pathname
85
+ * @param {object} params
86
+ * @returns {string}
87
+ */
88
+ getPublicUrl(pathname: string, params?: any, baseUrl?: string): string;
89
+ /**
90
+ * Sign a plain response, usually on auth success or error
91
+ *
92
+ * @method
93
+ * @param {object} params
94
+ * @param {object} params.response - response
95
+ * @param {string} params.errorMessage - error message, default to empty
96
+ * @param {string} params.successMessage - success message, default to empty
97
+ * @param {string} params.nextWorkflow - https://github.com/ArcBlock/ABT-DID-Protocol#concatenate-multiple-workflow
98
+ * @param {string} params.nextUrl - tell wallet do open this url in webview
99
+ * @param {object} params.cookies - key-value pairs to be set as cookie before open nextUrl
100
+ * @param {object} params.storages - key-value pairs to be set as localStorage before open nextUrl
101
+ * @param {string} baseUrl
102
+ * @param {object} request
103
+ * @returns {Promise<object>} { appPk, agentPk, authInfo }
104
+ */
105
+ signResponse(T104: _Lib.T105, baseUrl: string, request: any, extraParams?: _Lib.T106): Promise<any>;
106
+ /**
107
+ * Sign a auth response that returned to wallet: tell the wallet the appInfo/chainInfo
108
+ *
109
+ * @method
110
+ * @param {object} params
111
+ * @param {object} params.claims - info required by application to complete the auth
112
+ * @param {string} params.pathname - pathname to assemble callback url
113
+ * @param {string} params.baseUrl - baseUrl
114
+ * @param {object} params.challenge - random challenge to be included in the body
115
+ * @param {object} params.extraParams - extra query params and locale
116
+ * @param {object} params.request
117
+ * @param {object} params.context
118
+ * @param {string} params.context.token - action token
119
+ * @param {number} params.context.currentStep - current step
120
+ * @param {string} [params.context.sharedKey] - shared key between app and wallet
121
+ * @param {string} [params.context.encryptionKey] - encryption key from wallet
122
+ * @param {Function} [params.context.mfaCode] - function used to generate mfa code
123
+ * @param {string} params.context.userDid - decoded from req.query, base58
124
+ * @param {string} params.context.userPk - decoded from req.query, base58
125
+ * @param {string} params.context.didwallet - DID Wallet os and version
126
+ * @returns {Promise<object>} { appPk, agentPk, sharedKey, authInfo }
127
+ */
128
+ sign(T107: _Lib.T109): Promise<any>;
129
+ /**
130
+ * Determine chainInfo on the fly
131
+ *
132
+ * @param {object} params - contains the context of this request
133
+ * @param {object|undefined} [info=undefined] - chain info object or function
134
+ * @returns {Promise<ChainInfo>}
135
+ * @memberof WalletAuthenticator
136
+ */
137
+ getChainInfo(params: any, info: any): Promise<ChainInfo>;
138
+ /**
139
+ * Determine appInfo/memberAppInfo on the fly
140
+ *
141
+ * @param {object} params - contains the context of this request
142
+ * @param {string} key - appInfo | memberAppInfo
143
+ * @returns {Promise<ApplicationInfo>}
144
+ * @memberof WalletAuthenticator
145
+ */
146
+ getAppInfo(params: any, key?: string): Promise<ApplicationInfo>;
147
+ getWalletInfo(params: any): Promise<any>;
148
+ getDelegator(params: any): Promise<any>;
149
+ getDelegation(params: any): Promise<any>;
150
+ /**
151
+ * Verify a DID auth response sent from DID Wallet
152
+ *
153
+ * @method
154
+ * @param {object} data
155
+ * @param {string} [locale=en]
156
+ * @param {boolean} [enforceTimestamp=true]
157
+ * @returns Promise<boolean>
158
+ */
159
+ verify(data: any, locale?: string, enforceTimestamp?: boolean): Promise<_Lib.T110>;
160
+ genRequestedClaims(T111: _Lib.T112): Promise<any[]>;
161
+ getClaimInfo(T113: _Lib.T114): Promise<any>;
162
+ signature(T115: _Lib.T114): Promise<_Lib.T116>;
163
+ prepareTx(T117: _Lib.T114): Promise<_Lib.T118>;
164
+ tryWithTimeout(asyncFn: any): Promise<any>;
165
+ }
166
+ declare class BaseHandler extends events {
167
+ authenticator: any;
168
+ tokenStorage: any;
169
+ pathTransformer(...args: any[]): any;
170
+ onConnect(...args: any[]): any;
171
+ /**
172
+ * Creates an instance of DID Auth Handlers.
173
+ *
174
+ * @class
175
+ * @param {object} config
176
+ * @param {function} config.pathTransformer - function to transform path when generate action;
177
+ * @param {object} config.tokenStorage - function to generate action token
178
+ * @param {object} config.authenticator - Authenticator instance that can to jwt sign/verify
179
+ * @param {function} [config.onConnect=noop] - function called when wallet selected did
180
+ */
181
+ constructor(T119: _Lib.T120);
182
+ }
183
+ /**
184
+ * Events that are emitted during an DID Connect process
185
+ *
186
+ * - scanned: when the qrcode is scanned by wallet
187
+ * - succeed: when authentication complete
188
+ * - error: when something goes wrong
189
+ *
190
+ * @class WalletHandlers
191
+ * @extends {EventEmitter}
192
+ */
193
+ declare class WalletHandlers extends BaseHandler {
194
+ options: _Lib.T124;
195
+ /**
196
+ * Creates an instance of DID Auth Handlers.
197
+ *
198
+ * @class
199
+ * @param {object} config
200
+ * @param {object} config.tokenStorage - function to generate action token
201
+ * @param {object} config.authenticator - Authenticator instance that can to jwt sign/verify
202
+ * @param {function} [config.pathTransformer=null] - how should we update pathname
203
+ * @param {function} [config.onConnect=noop] - function called before each auth request send back to app, used to check for permission, throw error to halt the auth process
204
+ * @param {object} [config.options={}] - custom options to define all handlers attached
205
+ * @param {string} [config.options.prefix='/api/did'] - url prefix for this group endpoints
206
+ * @param {number} [config.options.cleanupDelay=60000] - how long to wait before cleanup finished session
207
+ * @param {string} [config.options.tokenKey='_t_'] - query param key for `token`
208
+ * @param {string} [config.options.encKey='_ek_'] - query param key for encryption key
209
+ * @param {string} [config.options.versionKey='_v_'] - query param key for protocol `version`
210
+ */
211
+ constructor(T121: _Lib.T123);
212
+ /**
213
+ * Attach routes and handlers for authenticator
214
+ * Now express app have route handlers attached to the following url
215
+ * - `GET /api/did/{action}/token` create new token
216
+ * - `GET /api/did/{action}/status` check for token status
217
+ * - `GET /api/did/{action}/timeout` expire a token
218
+ * - `GET /api/did/{action}/auth` create auth response
219
+ * - `POST /api/did/{action}/auth` process payment request
220
+ *
221
+ * @method
222
+ * @param {object} config
223
+ * @param {object} config.app - express instance to attach routes to
224
+ * @param {object} [config.claims] - claims for this request
225
+ * @param {string} config.action - action of this group of routes
226
+ * @param {function} [config.onStart=noop] - callback when a new action start
227
+ * @param {function} [config.onConnect=noop] - callback when a new action start
228
+ * @param {function} config.onAuth - callback when user completed auth in DID Wallet, and data posted back
229
+ * @param {function} [config.onDecline=noop] - callback when user has declined in wallet
230
+ * @param {function} [config.onComplete=noop] - callback when the whole auth process is done, action token is removed
231
+ * @param {function} [config.onExpire=noop] - callback when the action token expired
232
+ * @param {function} [config.onError=console.error] - callback when there are some errors
233
+ * @param {boolean|string|did} [config.authPrincipal=true] - whether should we do auth principal claim first
234
+ * @param {boolean} [config.persistentDynamicClaims=false] - whether should we persist dynamic claims
235
+ * @return void
236
+ */
237
+ attach(T125: _Lib.T126): void;
238
+ }
239
+ declare const _Lib: _Lib.T127;
240
+ declare namespace _Lib {
241
+ export interface T101 {
242
+ wallet: any;
243
+ }
244
+ export interface T103 {
245
+ baseUrl: string;
246
+ pathname: string;
247
+ token: string;
248
+ query: any;
249
+ }
250
+ export interface T105 {
251
+ response: any;
252
+ errorMessage: string;
253
+ successMessage: string;
254
+ nextWorkflow: string;
255
+ nextUrl: string;
256
+ cookies: any;
257
+ storages: any;
258
+ }
259
+ export interface T106 {
260
+ [key: string]: any;
261
+ }
262
+ export interface T108 {
263
+ token: string;
264
+ currentStep: number;
265
+ sharedKey?: string;
266
+ encryptionKey?: string;
267
+ mfaCode?: (...args: any[]) => any;
268
+ userDid: string;
269
+ userPk: string;
270
+ didwallet: string;
271
+ }
272
+ export interface T109 {
273
+ claims: any;
274
+ pathname: string;
275
+ baseUrl: string;
276
+ challenge: any;
277
+ extraParams: any;
278
+ request: any;
279
+ context: _Lib.T108;
280
+ }
281
+ export interface ChainInfo {
282
+ id: string;
283
+ type: string;
284
+ host: string;
285
+ }
286
+ export interface ApplicationInfo {
287
+ name: string;
288
+ description: string;
289
+ icon: string;
290
+ link: string;
291
+ path: string;
292
+ publisher: string;
293
+ }
294
+ export interface T110 {
295
+ token: any;
296
+ userDid: string;
297
+ userPk: any;
298
+ claims: any;
299
+ action: any;
300
+ challenge: any;
301
+ timestamp: string;
302
+ }
303
+ export interface T112 {
304
+ claims: any;
305
+ context: any;
306
+ extraParams: any;
307
+ }
308
+ export interface T114 {
309
+ claim: any;
310
+ context: any;
311
+ extraParams: any;
312
+ }
313
+ export interface T116 {
314
+ type: string;
315
+ description: any;
316
+ origin: string;
317
+ typeUrl: any;
318
+ display: any;
319
+ method: any;
320
+ digest: any;
321
+ chainInfo: any;
322
+ meta: any;
323
+ mfa: any;
324
+ nonce: any;
325
+ requirement: any;
326
+ }
327
+ export interface T118 {
328
+ type: string;
329
+ description: string;
330
+ partialTx: string;
331
+ display: any;
332
+ requirement: any;
333
+ chainInfo: any;
334
+ meta: any;
335
+ mfa: any;
336
+ nonce: any;
337
+ }
338
+ export interface T120 {
339
+ pathTransformer: (...args: any[]) => any;
340
+ tokenStorage: any;
341
+ authenticator: any;
342
+ onConnect?: (...args: any[]) => any;
343
+ }
344
+ export interface T122 {
345
+ prefix?: string;
346
+ cleanupDelay?: number;
347
+ tokenKey?: string;
348
+ encKey?: string;
349
+ versionKey?: string;
350
+ }
351
+ export interface T123 {
352
+ tokenStorage: any;
353
+ authenticator: any;
354
+ pathTransformer?: (...args: any[]) => any;
355
+ onConnect?: (...args: any[]) => any;
356
+ options?: _Lib.T122;
357
+ }
358
+ export interface T124 {
359
+ prefix: string;
360
+ cleanupDelay: number;
361
+ tokenKey: string;
362
+ encKey: string;
363
+ versionKey: string;
364
+ }
365
+ export interface T126 {
366
+ app: any;
367
+ claims?: any;
368
+ action: string;
369
+ onStart?: (...args: any[]) => any;
370
+ onConnect?: (...args: any[]) => any;
371
+ onAuth: (...args: any[]) => any;
372
+ onDecline?: (...args: any[]) => any;
373
+ onComplete?: (...args: any[]) => any;
374
+ onExpire?: (...args: any[]) => any;
375
+ onError?: (...args: any[]) => any;
376
+ authPrincipal?: any;
377
+ persistentDynamicClaims?: boolean;
378
+ }
379
+ export interface T127 {
380
+ WalletAuthenticator: typeof WalletAuthenticator;
381
+ WalletHandlers: typeof WalletHandlers;
382
+ }
383
+ }
384
+ export = _Lib;
package/lib/index.js ADDED
@@ -0,0 +1,7 @@
1
+ const WalletAuthenticator = require('./authenticator/wallet');
2
+ const WalletHandlers = require('./handlers/wallet');
3
+
4
+ module.exports = {
5
+ WalletAuthenticator,
6
+ WalletHandlers,
7
+ };
@@ -0,0 +1,46 @@
1
+ const AES = require('@ocap/mcrypto/lib/crypter/aes').default;
2
+ const { decode } = require('@arcblock/jwt');
3
+ const { fromBase58 } = require('@ocap/util');
4
+
5
+ const VERSION = '1.0.0';
6
+
7
+ const decrypt = (data, config = {}, dataKey = 'userInfo') => {
8
+ try {
9
+ decode(data[dataKey]);
10
+ return data;
11
+ } catch {
12
+ // Do nothing
13
+ }
14
+
15
+ if (config.sharedKey && data.version === VERSION) {
16
+ data[dataKey] = AES.decrypt(fromBase58(data[dataKey]), config.sharedKey, 'buffer').toString('utf8');
17
+ }
18
+ return data;
19
+ };
20
+
21
+ const encrypt = (data, config = {}, dataKey = 'authInfo') => {
22
+ const { clientVersion, sharedKey } = config || {};
23
+ if (data.sensitive && sharedKey && clientVersion === VERSION) {
24
+ data.version = VERSION;
25
+ data[dataKey] = AES.encrypt(data[dataKey], sharedKey, 'base58');
26
+ }
27
+
28
+ delete data.sensitive;
29
+
30
+ return data;
31
+ };
32
+
33
+ module.exports = {
34
+ decrypt,
35
+ encrypt,
36
+ VERSION,
37
+ PROTECTED_KEYS: ['challenge', 'nonce', 'sharedKey', 'encryptionKey'],
38
+ SESSION_STATUS: {
39
+ CREATED: 'created',
40
+ SUCCEED: 'succeed',
41
+ ERROR: 'error',
42
+ BUSY: 'busy',
43
+ SCANNED: 'scanned',
44
+ FORBIDDEN: 'forbidden',
45
+ },
46
+ };