@abtnode/blocklet-services 1.16.13-beta-55b3e93d → 1.16.13-beta-423a40b1
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/api/cache.js +20 -3
- package/api/index.js +9 -2
- package/api/libs/connect/session.js +20 -5
- package/api/libs/jwt.js +33 -17
- package/api/routes/connect/session.js +2 -2
- package/api/routes/oauth.js +50 -12
- package/api/routes/user.js +14 -7
- package/api/services/auth/connect/exchange-passport.js +1 -1
- package/api/services/auth/connect/invite.js +11 -2
- package/api/services/auth/connect/login.js +1 -1
- package/api/services/auth/connect/receive-transfer-app-owner.js +10 -2
- package/api/services/auth/connect/setup.js +1 -0
- package/api/services/auth/connect/switch-passport.js +2 -2
- package/api/services/auth/index.js +28 -6
- package/api/services/auth/session.js +92 -9
- package/api/util/index.js +39 -0
- package/build/asset-manifest.json +21 -21
- package/build/index.html +1 -1
- package/build/static/css/{76.33bb01dc.chunk.css → 125.1bbe7d61.chunk.css} +1 -1
- package/build/static/js/125.910ae6fb.chunk.js +3 -0
- package/build/static/js/343.eb7c9faf.chunk.js +2 -0
- package/build/static/js/359.0eb124b0.chunk.js +2 -0
- package/build/static/js/547.ce4b87b4.chunk.js +2 -0
- package/build/static/js/{573.db4a5d42.chunk.js → 573.5db9b322.chunk.js} +2 -2
- package/build/static/js/716.69235521.chunk.js +2 -0
- package/build/static/js/737.1f59e1c3.chunk.js +2 -0
- package/build/static/js/868.30686f6c.chunk.js +2 -0
- package/build/static/js/main.af84eb83.js +3 -0
- package/package.json +22 -22
- package/build/static/js/359.d6450ee2.chunk.js +0 -2
- package/build/static/js/547.0f340856.chunk.js +0 -2
- package/build/static/js/681.6b37e1e3.chunk.js +0 -2
- package/build/static/js/716.b48e64d9.chunk.js +0 -2
- package/build/static/js/737.5bcab5c2.chunk.js +0 -2
- package/build/static/js/76.5e4898b3.chunk.js +0 -3
- package/build/static/js/868.ac8df3a0.chunk.js +0 -2
- package/build/static/js/main.7fefe3b1.js +0 -3
- /package/build/static/js/{76.5e4898b3.chunk.js.LICENSE.txt → 125.910ae6fb.chunk.js.LICENSE.txt} +0 -0
- /package/build/static/js/{main.7fefe3b1.js.LICENSE.txt → main.af84eb83.js.LICENSE.txt} +0 -0
package/api/cache.js
CHANGED
|
@@ -3,12 +3,15 @@ const nodemailer = require('nodemailer');
|
|
|
3
3
|
const getBlockletInfo = require('@blocklet/meta/lib/info');
|
|
4
4
|
const md5 = require('@abtnode/util/lib/md5');
|
|
5
5
|
|
|
6
|
-
const
|
|
6
|
+
const cache = new LRU({
|
|
7
7
|
max: 100, // cache at most 100
|
|
8
8
|
maxAge: 60 * 60 * 1000, // cache for 1 hour
|
|
9
|
-
};
|
|
9
|
+
});
|
|
10
10
|
|
|
11
|
-
const
|
|
11
|
+
const sessionCacheDisabledUser = new LRU({
|
|
12
|
+
max: 10000,
|
|
13
|
+
maxAge: 86400 * 1000, // cache for 1 day
|
|
14
|
+
});
|
|
12
15
|
|
|
13
16
|
const keyFns = {
|
|
14
17
|
node() {
|
|
@@ -29,6 +32,9 @@ const keyFns = {
|
|
|
29
32
|
notificationConfig(did) {
|
|
30
33
|
return md5(`${did}:notificationConfig`);
|
|
31
34
|
},
|
|
35
|
+
sessionCacheDisabledUser(did) {
|
|
36
|
+
return md5(`sessionCacheDisabledUser:${did}`);
|
|
37
|
+
},
|
|
32
38
|
};
|
|
33
39
|
|
|
34
40
|
cache.getNodeInfo = async ({ node }) => {
|
|
@@ -112,6 +118,17 @@ cache.getTransport = ({ did, config, force }) => {
|
|
|
112
118
|
return transporter;
|
|
113
119
|
};
|
|
114
120
|
|
|
121
|
+
cache.sessionCacheDisabledUser = {
|
|
122
|
+
get: (did) => {
|
|
123
|
+
const cacheKey = cache.keyFns.sessionCacheDisabledUser(did);
|
|
124
|
+
return sessionCacheDisabledUser.get(cacheKey);
|
|
125
|
+
},
|
|
126
|
+
set: (did) => {
|
|
127
|
+
const cacheKey = cache.keyFns.sessionCacheDisabledUser(did);
|
|
128
|
+
return sessionCacheDisabledUser.set(cacheKey, true);
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
|
|
115
132
|
cache.keyFns = keyFns;
|
|
116
133
|
|
|
117
134
|
module.exports = cache;
|
package/api/index.js
CHANGED
|
@@ -68,6 +68,7 @@ module.exports = function createServer(node, serverOptions = {}) {
|
|
|
68
68
|
sessionTtl: process.env.ABT_NODE_SESSION_TTL,
|
|
69
69
|
webWalletUrl: 'https://web.abtwallet.io',
|
|
70
70
|
sessionTokenKey: 'login_token',
|
|
71
|
+
refreshTokenKey: 'refresh_token',
|
|
71
72
|
...serverOptions,
|
|
72
73
|
isProduction,
|
|
73
74
|
isE2E,
|
|
@@ -144,6 +145,10 @@ module.exports = function createServer(node, serverOptions = {}) {
|
|
|
144
145
|
logger.info('node update', { pid: process.pid });
|
|
145
146
|
cache.del(cache.keyFns.node());
|
|
146
147
|
});
|
|
148
|
+
eventHub.on(EVENTS.USER_PERMISSION_UPDATED, ({ teamDid, user } = {}) => {
|
|
149
|
+
logger.info('user permission updated', { teamDid, userDid: user?.did });
|
|
150
|
+
cache.sessionCacheDisabledUser.set(user?.did);
|
|
151
|
+
});
|
|
147
152
|
|
|
148
153
|
[BlockletInternalEvents.componentsUpdated, BlockletInternalEvents.appConfigChanged].forEach((name) => {
|
|
149
154
|
eventHub.on(name, (data) => {
|
|
@@ -226,8 +231,11 @@ module.exports = function createServer(node, serverOptions = {}) {
|
|
|
226
231
|
notificationService.sendToAppChannel.attach(server);
|
|
227
232
|
relayService.sendToRelay.attach(server);
|
|
228
233
|
|
|
234
|
+
// API: auth: before auth middleware
|
|
235
|
+
authRoutes.createSessionRoutes.init(server, node);
|
|
236
|
+
|
|
229
237
|
// Middleware: auth info
|
|
230
|
-
server.use(authMiddlewares.
|
|
238
|
+
server.use(authMiddlewares.sessionBearerToken);
|
|
231
239
|
server.use(authMiddlewares.userInfo);
|
|
232
240
|
|
|
233
241
|
// API: auth
|
|
@@ -239,7 +247,6 @@ module.exports = function createServer(node, serverOptions = {}) {
|
|
|
239
247
|
createConnectRelayRoutes.init(server, node, options, wsRouter);
|
|
240
248
|
authRoutes.attachDidAuthHandlers(server);
|
|
241
249
|
authRoutes.createPassportRoutes.init(server, node);
|
|
242
|
-
authRoutes.createSessionRoutes.init(server, node);
|
|
243
250
|
|
|
244
251
|
// API: gql
|
|
245
252
|
['/api/gql', '/api/preferences', '/api/uploads'].forEach((pathname) => {
|
|
@@ -40,7 +40,7 @@ const { getRolesFromAuthConfig, getBlockletAppIdList } = require('@blocklet/meta
|
|
|
40
40
|
|
|
41
41
|
const logger = require('@abtnode/logger')(require('../../../package.json').name);
|
|
42
42
|
|
|
43
|
-
const { isInvitedUserOnly } = require('../../util');
|
|
43
|
+
const { isInvitedUserOnly, createTokenFn, getDidConnectVersion } = require('../../util');
|
|
44
44
|
const { transferPassport } = require('../auth/utils');
|
|
45
45
|
const { generateTranslate } = require('../translate');
|
|
46
46
|
const { migrateAccount, declareAccount } = require('../../services/oauth');
|
|
@@ -204,7 +204,8 @@ module.exports = {
|
|
|
204
204
|
action,
|
|
205
205
|
}) => {
|
|
206
206
|
const blocklet = await request.getBlocklet();
|
|
207
|
-
const
|
|
207
|
+
const blockletInfo = await request.getBlockletInfo();
|
|
208
|
+
const { wallet, secret, name, passportColor, did: teamDid } = blockletInfo;
|
|
208
209
|
|
|
209
210
|
// Check user approved
|
|
210
211
|
const user = await node.getUser({
|
|
@@ -383,7 +384,13 @@ module.exports = {
|
|
|
383
384
|
}
|
|
384
385
|
|
|
385
386
|
// Generate new session token that client can save to localStorage
|
|
386
|
-
const
|
|
387
|
+
const createToken = createTokenFn(createSessionToken);
|
|
388
|
+
const sessionConfig = blocklet.settings?.session || {};
|
|
389
|
+
const { sessionToken, refreshToken } = createToken(
|
|
390
|
+
realDid,
|
|
391
|
+
{ secret, passport, role },
|
|
392
|
+
{ ...sessionConfig, didConnectVersion: getDidConnectVersion(request) }
|
|
393
|
+
);
|
|
387
394
|
logger.info(`${action}.success`, { userDid: realDid, role });
|
|
388
395
|
|
|
389
396
|
if (
|
|
@@ -403,6 +410,7 @@ module.exports = {
|
|
|
403
410
|
type: 'VerifiableCredential',
|
|
404
411
|
data: vc,
|
|
405
412
|
sessionToken,
|
|
413
|
+
refreshToken,
|
|
406
414
|
nextWorkflowData: {
|
|
407
415
|
userDid: realDid,
|
|
408
416
|
},
|
|
@@ -411,6 +419,7 @@ module.exports = {
|
|
|
411
419
|
|
|
412
420
|
return {
|
|
413
421
|
sessionToken,
|
|
422
|
+
refreshToken,
|
|
414
423
|
nextWorkflowData: {
|
|
415
424
|
userDid: realDid,
|
|
416
425
|
},
|
|
@@ -630,8 +639,14 @@ module.exports = {
|
|
|
630
639
|
);
|
|
631
640
|
|
|
632
641
|
// Generate new session token that client can save to localStorage
|
|
633
|
-
const
|
|
634
|
-
|
|
642
|
+
const createToken = createTokenFn(createSessionToken);
|
|
643
|
+
const sessionConfig = blocklet.settings?.session || {};
|
|
644
|
+
const { sessionToken, refreshToken } = createToken(
|
|
645
|
+
userDid,
|
|
646
|
+
{ secret, passport, role },
|
|
647
|
+
{ ...sessionConfig, didConnectVersion: getDidConnectVersion(request) }
|
|
648
|
+
);
|
|
649
|
+
return { sessionToken, refreshToken };
|
|
635
650
|
},
|
|
636
651
|
},
|
|
637
652
|
|
package/api/libs/jwt.js
CHANGED
|
@@ -12,18 +12,20 @@ const getUser = async (node, teamDid, userDid) => {
|
|
|
12
12
|
|
|
13
13
|
// eslint-disable-next-line no-unused-vars
|
|
14
14
|
const initJwt = (node, options) => {
|
|
15
|
-
|
|
15
|
+
// 保持默认有效期为 1 天
|
|
16
|
+
const ttl = options.sessionTtl || '1d';
|
|
16
17
|
|
|
17
|
-
const createSessionToken = (did, { role, secret, passport }) =>
|
|
18
|
+
const createSessionToken = (did, { role, secret, passport, expiresIn, tokenType }) =>
|
|
18
19
|
createAuthToken({
|
|
19
20
|
did,
|
|
20
21
|
passport,
|
|
21
22
|
role,
|
|
22
23
|
secret,
|
|
23
|
-
expiresIn: ttl,
|
|
24
|
+
expiresIn: expiresIn || ttl,
|
|
25
|
+
tokenType,
|
|
24
26
|
});
|
|
25
27
|
|
|
26
|
-
const verifySessionToken = (token, secret, teamDid) =>
|
|
28
|
+
const verifySessionToken = (token, secret, { checkFromDb, teamDid, checkToken } = {}) =>
|
|
27
29
|
// eslint-disable-next-line implicit-arrow-linebreak
|
|
28
30
|
new Promise((resolve, reject) => {
|
|
29
31
|
jwt.verify(token, secret, async (err, decoded) => {
|
|
@@ -31,29 +33,43 @@ const initJwt = (node, options) => {
|
|
|
31
33
|
return reject(err);
|
|
32
34
|
}
|
|
33
35
|
|
|
36
|
+
if (typeof checkToken === 'function') {
|
|
37
|
+
try {
|
|
38
|
+
await checkToken(decoded);
|
|
39
|
+
} catch (e) {
|
|
40
|
+
return reject(e);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
34
44
|
const { did, role, passport } = decoded;
|
|
45
|
+
let user;
|
|
35
46
|
if (!did) {
|
|
36
47
|
return reject(new Error('Invalid jwt token: invalid did'));
|
|
37
48
|
}
|
|
38
49
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
return reject(new Error('Invalid jwt token: invalid user'));
|
|
50
|
+
let isCheck = checkFromDb;
|
|
51
|
+
if (typeof checkFromDb === 'function') {
|
|
52
|
+
isCheck = checkFromDb(decoded);
|
|
43
53
|
}
|
|
44
54
|
|
|
45
|
-
if (
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
55
|
+
if (isCheck) {
|
|
56
|
+
// NOTICE: session 中的 did 是永久 did,不需要查询 connectedAccount
|
|
57
|
+
user = await getUser(node, teamDid, did);
|
|
58
|
+
if (!user) {
|
|
59
|
+
return reject(new Error('Invalid jwt token: invalid user'));
|
|
49
60
|
}
|
|
50
|
-
}
|
|
51
61
|
|
|
52
|
-
|
|
62
|
+
if (passport && passport.id) {
|
|
63
|
+
const valid = await node.isPassportValid({ teamDid, passportId: passport.id });
|
|
64
|
+
if (valid === false) {
|
|
65
|
+
return reject(new Error(`Passport ${passport.name} has been revoked`));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
53
68
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
69
|
+
user.role = role;
|
|
70
|
+
user.passport = passport;
|
|
71
|
+
} else {
|
|
72
|
+
user = { did, role, passport };
|
|
57
73
|
}
|
|
58
74
|
|
|
59
75
|
return resolve(user);
|
|
@@ -101,7 +101,7 @@ module.exports = {
|
|
|
101
101
|
try {
|
|
102
102
|
const { locale, currentConnected, responseClaims, challenge, currentStep } = req.body;
|
|
103
103
|
const { createSessionToken } = initJwt(node, options);
|
|
104
|
-
const sessionToken = await switchPassport.onApprove({
|
|
104
|
+
const { sessionToken, refreshToken } = await switchPassport.onApprove({
|
|
105
105
|
node,
|
|
106
106
|
request: req,
|
|
107
107
|
locale,
|
|
@@ -110,7 +110,7 @@ module.exports = {
|
|
|
110
110
|
userDid: currentConnected.userDid,
|
|
111
111
|
createSessionToken,
|
|
112
112
|
});
|
|
113
|
-
res.json({ sessionToken });
|
|
113
|
+
res.json({ sessionToken, refreshToken });
|
|
114
114
|
} catch (err) {
|
|
115
115
|
console.error(err);
|
|
116
116
|
res.json({ error: err.message });
|
package/api/routes/oauth.js
CHANGED
|
@@ -20,7 +20,7 @@ const { getAvatarByEmail, transferPassport, getAvatarByUrl } = require('../libs/
|
|
|
20
20
|
const initJwt = require('../libs/jwt');
|
|
21
21
|
const { sendToUser } = require('../libs/notification');
|
|
22
22
|
const { generateTranslate } = require('../libs/translate');
|
|
23
|
-
const { isInvitedUserOnly } = require('../util');
|
|
23
|
+
const { isInvitedUserOnly, createTokenFn, getDidConnectVersion } = require('../util');
|
|
24
24
|
const { ApiError } = require('../util/error');
|
|
25
25
|
|
|
26
26
|
const PREFIX = WELLKNOWN_SERVICE_PATH_PREFIX;
|
|
@@ -152,12 +152,24 @@ async function login(req, node, options) {
|
|
|
152
152
|
|
|
153
153
|
const { createSessionToken } = initJwt(node, options);
|
|
154
154
|
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
155
|
+
const createToken = createTokenFn(createSessionToken);
|
|
156
|
+
const sessionConfig = blocklet.settings?.session || {};
|
|
157
|
+
const { sessionToken, refreshToken } = createToken(
|
|
158
|
+
currentUser.did,
|
|
159
|
+
{
|
|
160
|
+
secret,
|
|
161
|
+
passport,
|
|
162
|
+
role: passport.role,
|
|
163
|
+
},
|
|
164
|
+
{ ...sessionConfig, didConnectVersion: getDidConnectVersion(req) }
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
// for backward compatibility
|
|
168
|
+
if (!getDidConnectVersion(req)) {
|
|
169
|
+
return sessionToken;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return { sessionToken, refreshToken };
|
|
161
173
|
}
|
|
162
174
|
|
|
163
175
|
async function invite(req, node, options) {
|
|
@@ -261,8 +273,21 @@ async function invite(req, node, options) {
|
|
|
261
273
|
|
|
262
274
|
const { createSessionToken } = initJwt(node, options);
|
|
263
275
|
|
|
264
|
-
const
|
|
265
|
-
|
|
276
|
+
const createToken = createTokenFn(createSessionToken);
|
|
277
|
+
const sessionConfig = blocklet.settings?.session || {};
|
|
278
|
+
|
|
279
|
+
const { sessionToken, refreshToken } = createToken(
|
|
280
|
+
userDid,
|
|
281
|
+
{ secret, passport, role },
|
|
282
|
+
{ ...sessionConfig, didConnectVersion: getDidConnectVersion(req) }
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
// for backward compatibility
|
|
286
|
+
if (!getDidConnectVersion(req)) {
|
|
287
|
+
return sessionToken;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
return { sessionToken, refreshToken };
|
|
266
291
|
}
|
|
267
292
|
|
|
268
293
|
// eslint-disable-next-line no-unused-vars
|
|
@@ -403,7 +428,7 @@ module.exports = {
|
|
|
403
428
|
server.post(`${prefix}/bind`, async (req, res) => {
|
|
404
429
|
try {
|
|
405
430
|
await bind(req, node, options);
|
|
406
|
-
res.status(200).
|
|
431
|
+
res.status(200).json({});
|
|
407
432
|
} catch (err) {
|
|
408
433
|
logger.error('Failed bind oauth', { error: err });
|
|
409
434
|
if (err instanceof ApiError) {
|
|
@@ -417,6 +442,7 @@ module.exports = {
|
|
|
417
442
|
server.post(`${prefix}/switch`, async (req, res) => {
|
|
418
443
|
const userDid = req.user.did;
|
|
419
444
|
const { passportId } = req.body;
|
|
445
|
+
const blocklet = await req.getBlocklet();
|
|
420
446
|
const { did: teamDid, secret } = await req.getBlockletInfo();
|
|
421
447
|
// NOTICE: 这里获取的 did 是当前登录用户的永久 did,无需查询 connectedAccount
|
|
422
448
|
const user = await node.getUser({ teamDid, user: { did: userDid } });
|
|
@@ -432,8 +458,20 @@ module.exports = {
|
|
|
432
458
|
node
|
|
433
459
|
);
|
|
434
460
|
const { createSessionToken } = initJwt(node, options);
|
|
435
|
-
const
|
|
436
|
-
|
|
461
|
+
const createToken = createTokenFn(createSessionToken);
|
|
462
|
+
const sessionConfig = blocklet.settings?.session || {};
|
|
463
|
+
const { sessionToken, refreshToken } = createToken(
|
|
464
|
+
userDid,
|
|
465
|
+
{ secret, passport, role: passport.role },
|
|
466
|
+
{ ...sessionConfig, didConnectVersion: getDidConnectVersion(req) }
|
|
467
|
+
);
|
|
468
|
+
|
|
469
|
+
// for backward compatibility
|
|
470
|
+
if (!getDidConnectVersion(req)) {
|
|
471
|
+
res.status(200).send(sessionToken);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
res.status(200).json({ sessionToken, refreshToken });
|
|
437
475
|
});
|
|
438
476
|
|
|
439
477
|
/**
|
package/api/routes/user.js
CHANGED
|
@@ -7,7 +7,7 @@ const logger = require('@abtnode/logger')('blocklet-services:user');
|
|
|
7
7
|
const { isFromPublicKey } = require('@arcblock/did');
|
|
8
8
|
|
|
9
9
|
const { generateTranslate } = require('../libs/translate');
|
|
10
|
-
const { isInvitedUserOnly } = require('../util');
|
|
10
|
+
const { isInvitedUserOnly, createTokenFn, getDidConnectVersion } = require('../util');
|
|
11
11
|
const initJwt = require('../libs/jwt');
|
|
12
12
|
const { getAvatarByUrl } = require('../libs/auth/utils');
|
|
13
13
|
const { ApiError } = require('../util/error');
|
|
@@ -207,6 +207,7 @@ async function login(req, node, options) {
|
|
|
207
207
|
throw new ApiError(400, t('needComponentId', locale));
|
|
208
208
|
}
|
|
209
209
|
const { did: teamDid, wallet: blockletWallet, secret } = await req.getBlockletInfo();
|
|
210
|
+
const blocklet = await req.getBlocklet();
|
|
210
211
|
|
|
211
212
|
let doc;
|
|
212
213
|
if (provider === 'wallet') {
|
|
@@ -233,12 +234,18 @@ async function login(req, node, options) {
|
|
|
233
234
|
|
|
234
235
|
const { createSessionToken } = initJwt(node, options);
|
|
235
236
|
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
237
|
+
const createToken = createTokenFn(createSessionToken);
|
|
238
|
+
const sessionConfig = blocklet.settings?.session || {};
|
|
239
|
+
const { sessionToken, refreshToken } = createToken(
|
|
240
|
+
doc.did,
|
|
241
|
+
{
|
|
242
|
+
secret,
|
|
243
|
+
passport,
|
|
244
|
+
role: passport.role,
|
|
245
|
+
},
|
|
246
|
+
{ ...sessionConfig, didConnectVersion: getDidConnectVersion(req) }
|
|
247
|
+
);
|
|
248
|
+
return { user: doc, token: sessionToken, refreshToken };
|
|
242
249
|
}
|
|
243
250
|
|
|
244
251
|
module.exports = {
|
|
@@ -46,7 +46,7 @@ module.exports = function createRoutes(node, authenticator, createSessionToken)
|
|
|
46
46
|
action: 'exchangePassport',
|
|
47
47
|
});
|
|
48
48
|
|
|
49
|
-
await updateSession({ sessionToken: result.sessionToken }, true);
|
|
49
|
+
await updateSession({ sessionToken: result.sessionToken, refreshToken: result.refreshToken }, true);
|
|
50
50
|
|
|
51
51
|
return result;
|
|
52
52
|
} catch (err) {
|
|
@@ -10,6 +10,8 @@ const {
|
|
|
10
10
|
const { NODE_SERVICES, WELLKNOWN_SERVICE_PATH_PREFIX } = require('@abtnode/constant');
|
|
11
11
|
const logger = require('@abtnode/logger')(require('../../../../package.json').name);
|
|
12
12
|
|
|
13
|
+
const { createTokenFn, getDidConnectVersion } = require('../../../util');
|
|
14
|
+
|
|
13
15
|
module.exports = function createRoutes(node, authenticator, createSessionToken) {
|
|
14
16
|
return {
|
|
15
17
|
action: 'invite',
|
|
@@ -54,6 +56,7 @@ module.exports = function createRoutes(node, authenticator, createSessionToken)
|
|
|
54
56
|
const { locale, inviteId } = extraParams;
|
|
55
57
|
const nodeInfo = await req.getNodeInfo();
|
|
56
58
|
const { secret } = await req.getBlockletInfo();
|
|
59
|
+
const blocklet = await req.getBlocklet();
|
|
57
60
|
const teamDid = req.headers['x-blocklet-did'];
|
|
58
61
|
const statusEndpointBaseUrl = joinUrl(baseUrl, WELLKNOWN_SERVICE_PATH_PREFIX);
|
|
59
62
|
const endpoint = baseUrl;
|
|
@@ -73,8 +76,14 @@ module.exports = function createRoutes(node, authenticator, createSessionToken)
|
|
|
73
76
|
});
|
|
74
77
|
|
|
75
78
|
// Generate new session token that client can save to localStorage
|
|
76
|
-
const
|
|
77
|
-
|
|
79
|
+
const createToken = createTokenFn(createSessionToken);
|
|
80
|
+
const sessionConfig = blocklet.settings?.session || {};
|
|
81
|
+
const { sessionToken, refreshToken } = createToken(
|
|
82
|
+
userDid,
|
|
83
|
+
{ secret, passport, role },
|
|
84
|
+
{ ...sessionConfig, didConnectVersion: getDidConnectVersion(req) }
|
|
85
|
+
);
|
|
86
|
+
await updateSession({ sessionToken, refreshToken }, true);
|
|
78
87
|
await updateSession({ passportId: response.data.id });
|
|
79
88
|
logger.info('invite.success', { userDid });
|
|
80
89
|
|
|
@@ -36,7 +36,7 @@ module.exports = function createRoutes(node, authenticator, createSessionToken)
|
|
|
36
36
|
action: 'login',
|
|
37
37
|
});
|
|
38
38
|
|
|
39
|
-
await updateSession({ sessionToken: result.sessionToken }, true);
|
|
39
|
+
await updateSession({ sessionToken: result.sessionToken, refreshToken: result.refreshToken }, true);
|
|
40
40
|
|
|
41
41
|
return result;
|
|
42
42
|
} catch (err) {
|
|
@@ -19,6 +19,8 @@ const { getBlockletChainInfo, isInProgress } = require('@blocklet/meta/lib/util'
|
|
|
19
19
|
const { ROLES } = require('@abtnode/constant');
|
|
20
20
|
const logger = require('@abtnode/logger')('blocklet-service:transfer-blocklet-owner');
|
|
21
21
|
|
|
22
|
+
const { createTokenFn, getDidConnectVersion } = require('../../../util');
|
|
23
|
+
|
|
22
24
|
const migrateAppOnChain = async (blocklet, oldSk, newSk) => {
|
|
23
25
|
if (process.env.NODE_ENV === 'test') {
|
|
24
26
|
return;
|
|
@@ -360,8 +362,14 @@ module.exports = function createRoutes(node, _, createSessionToken) {
|
|
|
360
362
|
logger.info('transfer ownership success', { userDid });
|
|
361
363
|
|
|
362
364
|
// Generate new session token that client can save to localStorage
|
|
363
|
-
const
|
|
364
|
-
|
|
365
|
+
const createToken = createTokenFn(createSessionToken);
|
|
366
|
+
const sessionConfig = blocklet.settings?.session || {};
|
|
367
|
+
const { sessionToken, refreshToken } = createToken(
|
|
368
|
+
userDid,
|
|
369
|
+
{ secret, passport: vc, role },
|
|
370
|
+
{ ...sessionConfig, didConnectVersion: getDidConnectVersion(req) }
|
|
371
|
+
);
|
|
372
|
+
await updateSession({ sessionToken, refreshToken }, true);
|
|
365
373
|
await updateSession({ passportId: vc?.id });
|
|
366
374
|
logger.info('invite.success', { userDid });
|
|
367
375
|
|
|
@@ -110,6 +110,7 @@ module.exports = function createRoutes(node, _authenticator, createSessionToken)
|
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
// Generate new session token that client can save to localStorage
|
|
113
|
+
// HACK: 此处没有 passportId,所以特意不设置 refreshToken,失效后下次登录就能选择合适的 passport
|
|
113
114
|
const sessionToken = await createSessionToken(userDid, { secret, role: 'owner' });
|
|
114
115
|
await updateSession({ sessionToken }, true);
|
|
115
116
|
logger.info('setup.connect.success', { userDid });
|
|
@@ -17,7 +17,7 @@ module.exports = function createRoutes(node, authenticator, createSessionToken)
|
|
|
17
17
|
},
|
|
18
18
|
|
|
19
19
|
onAuth: async ({ claims, challenge, userDid, updateSession, extraParams, req }) => {
|
|
20
|
-
const sessionToken = await onApprove({
|
|
20
|
+
const { sessionToken, refreshToken } = await onApprove({
|
|
21
21
|
node,
|
|
22
22
|
request: req,
|
|
23
23
|
challenge,
|
|
@@ -27,7 +27,7 @@ module.exports = function createRoutes(node, authenticator, createSessionToken)
|
|
|
27
27
|
createSessionToken,
|
|
28
28
|
});
|
|
29
29
|
|
|
30
|
-
await updateSession({ sessionToken }, true);
|
|
30
|
+
await updateSession({ sessionToken, refreshToken }, true);
|
|
31
31
|
},
|
|
32
32
|
};
|
|
33
33
|
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
const get = require('lodash/get');
|
|
3
3
|
const cookie = require('cookie');
|
|
4
4
|
const minimatch = require('minimatch');
|
|
5
|
-
const bearerToken = require('express-bearer-token');
|
|
5
|
+
const bearerToken = require('@abtnode/util/lib/express-bearer-token');
|
|
6
6
|
|
|
7
7
|
const validators = require('@blocklet/sdk/lib/validators');
|
|
8
8
|
const {
|
|
@@ -39,6 +39,7 @@ const createSessionRoutes = require('./session');
|
|
|
39
39
|
const createPassportRoutes = require('./passport');
|
|
40
40
|
const { getRedirectUrl } = require('../../util');
|
|
41
41
|
const createGetDIDSpacesEndpointRoutes = require('./connect/get-did-spaces-endpoint');
|
|
42
|
+
const { sessionCacheDisabledUser } = require('../../cache');
|
|
42
43
|
|
|
43
44
|
const getTokenFromWsConnect = (req, options) => {
|
|
44
45
|
const cookies = cookie.parse(req.headers.cookie || '');
|
|
@@ -60,6 +61,8 @@ const isDevWsConnect = async (req) => {
|
|
|
60
61
|
const REASON_404 = 'Not Found';
|
|
61
62
|
|
|
62
63
|
const init = ({ node, options }) => {
|
|
64
|
+
const { createSessionToken, verifySessionToken } = initJwt(node, options);
|
|
65
|
+
|
|
63
66
|
/**
|
|
64
67
|
* set user info to req.user
|
|
65
68
|
*/
|
|
@@ -68,7 +71,12 @@ const init = ({ node, options }) => {
|
|
|
68
71
|
if (token) {
|
|
69
72
|
const teamDid = req.getBlockletDid();
|
|
70
73
|
const { secret } = await req.getBlockletInfo();
|
|
71
|
-
const
|
|
74
|
+
const opt = {
|
|
75
|
+
checkFromDb: (decoded) => sessionCacheDisabledUser.get(decoded?.did),
|
|
76
|
+
teamDid,
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const user = await verifySessionToken(token, secret, opt);
|
|
72
80
|
req.user = user;
|
|
73
81
|
}
|
|
74
82
|
} catch {
|
|
@@ -131,14 +139,13 @@ const init = ({ node, options }) => {
|
|
|
131
139
|
return {};
|
|
132
140
|
};
|
|
133
141
|
|
|
134
|
-
const { createSessionToken, verifySessionToken } = initJwt(node, options);
|
|
135
142
|
const { authenticator, handlers } = initAuth(node, options);
|
|
136
143
|
|
|
137
144
|
const middlewares = {};
|
|
138
145
|
const routes = {};
|
|
139
146
|
|
|
140
147
|
// auth middleware for http request
|
|
141
|
-
middlewares.
|
|
148
|
+
middlewares.sessionBearerToken = bearerToken({
|
|
142
149
|
queryKey: options.sessionTokenKey,
|
|
143
150
|
bodyKey: options.sessionTokenKey,
|
|
144
151
|
headerKey: 'Bearer',
|
|
@@ -149,6 +156,12 @@ const init = ({ node, options }) => {
|
|
|
149
156
|
},
|
|
150
157
|
});
|
|
151
158
|
|
|
159
|
+
middlewares.refreshBearerToken = bearerToken({
|
|
160
|
+
bodyKey: options.refreshTokenKey,
|
|
161
|
+
headerKey: 'Bearer',
|
|
162
|
+
reqKey: 'refreshToken',
|
|
163
|
+
});
|
|
164
|
+
|
|
152
165
|
// set user info to req.user and req.headers
|
|
153
166
|
middlewares.userInfo = async (req, res, next) => {
|
|
154
167
|
const { token } = req;
|
|
@@ -184,8 +197,17 @@ const init = ({ node, options }) => {
|
|
|
184
197
|
|
|
185
198
|
// public http api
|
|
186
199
|
routes.createPassportRoutes = createPassportRoutes;
|
|
187
|
-
|
|
188
|
-
|
|
200
|
+
routes.createSessionRoutes = {
|
|
201
|
+
// eslint-disable-next-line no-shadow
|
|
202
|
+
init: (router, node) =>
|
|
203
|
+
createSessionRoutes.init(router, node, createSessionToken, {
|
|
204
|
+
...options,
|
|
205
|
+
middlewares,
|
|
206
|
+
ensureUser,
|
|
207
|
+
createSessionToken,
|
|
208
|
+
verifySessionToken,
|
|
209
|
+
}),
|
|
210
|
+
};
|
|
189
211
|
|
|
190
212
|
const ensureWsUser = async (req) => {
|
|
191
213
|
const token = getTokenFromWsConnect(req, options);
|