@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.
- package/LICENSE +13 -0
- package/README.md +211 -0
- package/lib/authenticator/base.js +98 -0
- package/lib/authenticator/wallet.js +768 -0
- package/lib/handlers/base.js +49 -0
- package/lib/handlers/util.js +943 -0
- package/lib/handlers/wallet.js +168 -0
- package/lib/index.d.ts +384 -0
- package/lib/index.js +7 -0
- package/lib/protocol.js +46 -0
- package/lib/schema/claims.js +256 -0
- package/lib/schema/index.js +56 -0
- package/package.json +86 -0
|
@@ -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
package/lib/protocol.js
ADDED
|
@@ -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
|
+
};
|