@blocklet/sdk 1.8.66 → 1.8.67-beta-65933c91
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/lib/component/index.js +5 -14
- package/lib/connect/authenticator.js +4 -1
- package/lib/connect/handler.js +4 -13
- package/lib/connect/shared.js +17 -13
- package/lib/database/index.js +18 -25
- package/lib/embed/index.d.ts +9 -0
- package/lib/embed/index.js +13 -0
- package/lib/embed/message.d.ts +26 -0
- package/lib/embed/message.js +134 -0
- package/lib/embed/utils.d.ts +7 -0
- package/lib/embed/utils.js +95 -0
- package/lib/middlewares/auth.d.ts +6 -1
- package/lib/middlewares/auth.js +21 -24
- package/lib/middlewares/index.d.ts +5 -1
- package/lib/middlewares/user.js +2 -11
- package/lib/service/auth.d.ts +1 -1
- package/lib/service/auth.js +10 -19
- package/lib/service/notification.d.ts +3 -0
- package/lib/service/notification.js +11 -14
- package/lib/util/env.js +1 -1
- package/lib/util/send-notification.d.ts +3 -2
- package/lib/util/send-notification.js +45 -21
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/wallet-authenticator.js +4 -1
- package/lib/wallet-handler.d.ts +7 -5
- package/lib/wallet-handler.js +28 -40
- package/package.json +13 -11
package/lib/component/index.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
@@ -25,9 +16,9 @@ const sign = (data) => {
|
|
|
25
16
|
const signData = typeof data === 'undefined' ? {} : data;
|
|
26
17
|
return { 'x-component-sig': wallet.sign((0, json_stable_stringify_1.default)(signData)) };
|
|
27
18
|
};
|
|
28
|
-
const doCall = ({ url, data }) =>
|
|
19
|
+
const doCall = async ({ url, data }) => {
|
|
29
20
|
try {
|
|
30
|
-
const resp =
|
|
21
|
+
const resp = await axios_1.default.post(url, data, { headers: sign(data), timeout: 60000 });
|
|
31
22
|
config_1.logger.info(`call ${url} api success`);
|
|
32
23
|
return resp;
|
|
33
24
|
}
|
|
@@ -40,7 +31,7 @@ const doCall = ({ url, data }) => __awaiter(void 0, void 0, void 0, function* ()
|
|
|
40
31
|
});
|
|
41
32
|
throw new Error(`call ${url} api failed`);
|
|
42
33
|
}
|
|
43
|
-
}
|
|
34
|
+
};
|
|
44
35
|
const parsePorts = () => JSON.parse(process.env.BLOCKLET_WEB_PORTS);
|
|
45
36
|
const getWebEndpoint = (name) => {
|
|
46
37
|
const ports = parsePorts();
|
|
@@ -68,11 +59,11 @@ const parseMountPoints = () => {
|
|
|
68
59
|
});
|
|
69
60
|
return mountPoints;
|
|
70
61
|
};
|
|
71
|
-
const call = ({ name, path: _path, data }) =>
|
|
62
|
+
const call = async ({ name, path: _path, data }) => {
|
|
72
63
|
const baseURL = name ? getChildWebEndpoint(name) : getParentWebEndpoint();
|
|
73
64
|
const url = (0, url_join_1.default)(baseURL, _path);
|
|
74
65
|
return doCall({ url, data });
|
|
75
|
-
}
|
|
66
|
+
};
|
|
76
67
|
exports.call = call;
|
|
77
68
|
const getComponentMountPoint = (keyword) => {
|
|
78
69
|
const mountPoints = parseMountPoints();
|
|
@@ -9,7 +9,10 @@ const shared_1 = __importDefault(require("./shared"));
|
|
|
9
9
|
class BlockletAuthenticator extends authenticator_1.Authenticator {
|
|
10
10
|
constructor(options = {}) {
|
|
11
11
|
(0, check_blocklet_env_1.default)();
|
|
12
|
-
super(
|
|
12
|
+
super({
|
|
13
|
+
wallet: (0, wallet_1.default)(),
|
|
14
|
+
...(0, shared_1.default)(options),
|
|
15
|
+
});
|
|
13
16
|
}
|
|
14
17
|
}
|
|
15
18
|
module.exports = BlockletAuthenticator;
|
package/lib/connect/handler.js
CHANGED
|
@@ -22,15 +22,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
-
});
|
|
33
|
-
};
|
|
34
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
27
|
};
|
|
@@ -60,8 +51,8 @@ const createConnectHandlers = ({ authenticator, storage, logger = consoleLogger,
|
|
|
60
51
|
socketPathname,
|
|
61
52
|
});
|
|
62
53
|
const originCreateHandler = handlers.handleSessionCreate;
|
|
63
|
-
handlers.handleSessionCreate = (context) =>
|
|
64
|
-
const session =
|
|
54
|
+
handlers.handleSessionCreate = async (context) => {
|
|
55
|
+
const session = await originCreateHandler(context);
|
|
65
56
|
const connectedDid = getConnectedDid(session);
|
|
66
57
|
// send notification to wallet to trigger wallet to auto connect
|
|
67
58
|
if (connectedDid) {
|
|
@@ -88,12 +79,12 @@ const createConnectHandlers = ({ authenticator, storage, logger = consoleLogger,
|
|
|
88
79
|
}
|
|
89
80
|
// sendNotificationFn maybe custom function so we need params
|
|
90
81
|
const sendFn = sendNotificationFn || notification_1.sendToUser.bind(notification_1.default);
|
|
91
|
-
sendFn(connectedDid, message,
|
|
82
|
+
sendFn(connectedDid, message, { ...context, session }).catch((err) => {
|
|
92
83
|
console.error(err);
|
|
93
84
|
});
|
|
94
85
|
}
|
|
95
86
|
return session;
|
|
96
|
-
}
|
|
87
|
+
};
|
|
97
88
|
return handlers;
|
|
98
89
|
};
|
|
99
90
|
module.exports = createConnectHandlers;
|
package/lib/connect/shared.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
@@ -16,10 +7,23 @@ const util_1 = require("@blocklet/meta/lib/util");
|
|
|
16
7
|
const constants_1 = require("../util/constants");
|
|
17
8
|
// wraps value in closure or returns closure
|
|
18
9
|
const closure = (value) => (typeof value === 'function' ? value : () => value);
|
|
19
|
-
const connectShared = (options = {}) => (
|
|
20
|
-
|
|
10
|
+
const connectShared = (options = {}) => ({
|
|
11
|
+
chainInfo: () => (0, util_1.getChainInfo)(process.env),
|
|
12
|
+
...options,
|
|
13
|
+
appInfo: async (...args) => {
|
|
14
|
+
const info = await closure(options.appInfo)(...args);
|
|
21
15
|
const { request, baseUrl } = args[0];
|
|
22
16
|
const groupPathPrefix = request.headers['x-group-path-prefix'] || '/';
|
|
23
|
-
return
|
|
24
|
-
|
|
17
|
+
return {
|
|
18
|
+
name: process.env.BLOCKLET_APP_NAME,
|
|
19
|
+
description: process.env.BLOCKLET_APP_DESCRIPTION,
|
|
20
|
+
...(info || {}),
|
|
21
|
+
link: (0, util_1.getConnectAppUrl)(args[0]),
|
|
22
|
+
icon: (0, url_join_1.default)(baseUrl, constants_1.SERVICE_PREFIX, `/blocklet/logo?v=${process.env.BLOCKLET_APP_VERSION || ''}`),
|
|
23
|
+
updateSubEndpoint: true,
|
|
24
|
+
subscriptionEndpoint: (0, url_join_1.default)(groupPathPrefix, constants_1.SERVICE_PREFIX, 'websocket'),
|
|
25
|
+
nodeDid: process.env.ABT_NODE_DID,
|
|
26
|
+
};
|
|
27
|
+
},
|
|
28
|
+
});
|
|
25
29
|
module.exports = connectShared;
|
package/lib/database/index.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
@@ -28,27 +19,29 @@ class DataBase extends core_1.DataStore {
|
|
|
28
19
|
const DB_DIR = path_1.default.join(process.env.BLOCKLET_DATA_DIR, 'db');
|
|
29
20
|
fs_extra_1.default.ensureDirSync(DB_DIR);
|
|
30
21
|
const filename = options.filename || path_1.default.join(DB_DIR, `${name}.db`);
|
|
31
|
-
super(
|
|
22
|
+
super({
|
|
23
|
+
filename,
|
|
24
|
+
autoload: true,
|
|
25
|
+
timestampData: true,
|
|
26
|
+
onload: (err) => {
|
|
32
27
|
if (err) {
|
|
33
28
|
console.error(`failed to load disk database ${filename}`, err);
|
|
34
29
|
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
exists(...args) {
|
|
38
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
39
|
-
const doc = yield this.findOne(...args);
|
|
40
|
-
return !!doc;
|
|
30
|
+
},
|
|
31
|
+
...options,
|
|
41
32
|
});
|
|
42
33
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
34
|
+
async exists(...args) {
|
|
35
|
+
const doc = await this.findOne(...args);
|
|
36
|
+
return !!doc;
|
|
37
|
+
}
|
|
38
|
+
async paginate({ condition = {}, sort = {}, page = 1, size = 100, projection = {} }) {
|
|
39
|
+
return this.cursor(condition)
|
|
40
|
+
.sort(sort)
|
|
41
|
+
.skip(Math.max(page * size - size, 0))
|
|
42
|
+
.limit(Math.max(size, 1))
|
|
43
|
+
.projection(projection)
|
|
44
|
+
.exec();
|
|
52
45
|
}
|
|
53
46
|
}
|
|
54
47
|
module.exports = DataBase;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Request, Response } from 'express';
|
|
2
|
+
import { generateBlockletEmbed } from './utils';
|
|
3
|
+
declare const expressEmbed: (req: Request, res: Response) => Promise<void>;
|
|
4
|
+
declare const _default: {
|
|
5
|
+
expressEmbed: (req: Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: Response<any, Record<string, any>>) => Promise<void>;
|
|
6
|
+
generateBlockletEmbed: typeof generateBlockletEmbed;
|
|
7
|
+
};
|
|
8
|
+
export default _default;
|
|
9
|
+
export { expressEmbed, generateBlockletEmbed };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateBlockletEmbed = exports.expressEmbed = void 0;
|
|
4
|
+
const utils_1 = require("./utils");
|
|
5
|
+
Object.defineProperty(exports, "generateBlockletEmbed", { enumerable: true, get: function () { return utils_1.generateBlockletEmbed; } });
|
|
6
|
+
const expressEmbed = async (req, res) => {
|
|
7
|
+
const { query = {} } = req;
|
|
8
|
+
const { url = '' } = query;
|
|
9
|
+
const data = await (0, utils_1.getBlockletEmbedFromUrl)(url);
|
|
10
|
+
res.json(data);
|
|
11
|
+
};
|
|
12
|
+
exports.expressEmbed = expressEmbed;
|
|
13
|
+
exports.default = { expressEmbed, generateBlockletEmbed: utils_1.generateBlockletEmbed };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
type InstanceType = 'client' | 'server';
|
|
2
|
+
type MessageType = string;
|
|
3
|
+
interface Callback {
|
|
4
|
+
(...args: any[]): void;
|
|
5
|
+
}
|
|
6
|
+
declare class Message {
|
|
7
|
+
id: string;
|
|
8
|
+
type: InstanceType;
|
|
9
|
+
private bc;
|
|
10
|
+
private eventMap;
|
|
11
|
+
init: (cb: Callback) => void;
|
|
12
|
+
onInit: (getData: () => any) => void;
|
|
13
|
+
close: () => void;
|
|
14
|
+
constructor(id: string, type?: InstanceType);
|
|
15
|
+
on(type: MessageType, cb: Callback): void;
|
|
16
|
+
off(type: MessageType, cb: Callback): void;
|
|
17
|
+
once(type: MessageType, cb: Callback): void;
|
|
18
|
+
send(type: MessageType, payload: any): void;
|
|
19
|
+
}
|
|
20
|
+
declare function useMessage(id?: string, type?: InstanceType): any;
|
|
21
|
+
declare const _default: {
|
|
22
|
+
useMessage: typeof useMessage;
|
|
23
|
+
Message: typeof Message;
|
|
24
|
+
};
|
|
25
|
+
export default _default;
|
|
26
|
+
export { useMessage, Message };
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Message = exports.useMessage = void 0;
|
|
4
|
+
const INIT = '__init';
|
|
5
|
+
const ON_INIT = '__on-init';
|
|
6
|
+
function checkKey(typeKey) {
|
|
7
|
+
return !typeKey.startsWith(INIT);
|
|
8
|
+
}
|
|
9
|
+
function ensureType(type) {
|
|
10
|
+
if (!checkKey(type)) {
|
|
11
|
+
throw new Error(`Type can't starts with ${INIT}`);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function notExist() {
|
|
15
|
+
console.error('function not exist');
|
|
16
|
+
}
|
|
17
|
+
class Message {
|
|
18
|
+
constructor(id, type = 'client') {
|
|
19
|
+
this.id = id;
|
|
20
|
+
this.type = type;
|
|
21
|
+
const bc = new BroadcastChannel(this.id);
|
|
22
|
+
this.bc = bc;
|
|
23
|
+
this.eventMap = new Map();
|
|
24
|
+
const onMessage = (event) => {
|
|
25
|
+
const { data } = event;
|
|
26
|
+
const { type: messageType, payload, id: dataId } = data;
|
|
27
|
+
if (dataId === this.id) {
|
|
28
|
+
const cbList = this.eventMap.get(messageType) || [];
|
|
29
|
+
cbList.forEach((cbItem) => {
|
|
30
|
+
cbItem(payload);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
window.addEventListener('message', onMessage, false);
|
|
35
|
+
this.close = () => {
|
|
36
|
+
window.removeEventListener('message', onMessage, false);
|
|
37
|
+
// v1 message
|
|
38
|
+
this.bc.close();
|
|
39
|
+
};
|
|
40
|
+
// v1 message
|
|
41
|
+
bc.onmessage = ({ data }) => {
|
|
42
|
+
const { type: messageType, payload } = data;
|
|
43
|
+
const cbList = this.eventMap.get(messageType) || [];
|
|
44
|
+
cbList.forEach((cbItem) => {
|
|
45
|
+
cbItem(payload);
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
this.init = notExist;
|
|
49
|
+
this.onInit = notExist;
|
|
50
|
+
if (type === 'server') {
|
|
51
|
+
this.onInit = (getData = () => null) => {
|
|
52
|
+
this.eventMap.set(INIT, [
|
|
53
|
+
(listenKey) => {
|
|
54
|
+
const initData = getData();
|
|
55
|
+
this.send(listenKey, initData);
|
|
56
|
+
},
|
|
57
|
+
]);
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
if (type === 'client') {
|
|
61
|
+
this.init = (cb) => {
|
|
62
|
+
const uniqueId = String(+new Date());
|
|
63
|
+
const listenKey = `${ON_INIT}_${uniqueId}`;
|
|
64
|
+
this.once(listenKey, cb);
|
|
65
|
+
this.send(INIT, listenKey);
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
on(type, cb) {
|
|
70
|
+
ensureType(type);
|
|
71
|
+
const cbList = this.eventMap.get(type) || [];
|
|
72
|
+
cbList.push(cb);
|
|
73
|
+
this.eventMap.set(type, cbList);
|
|
74
|
+
}
|
|
75
|
+
off(type, cb) {
|
|
76
|
+
ensureType(type);
|
|
77
|
+
const cbList = this.eventMap.get(type) || [];
|
|
78
|
+
if (cb) {
|
|
79
|
+
const index = cbList.indexOf(cb);
|
|
80
|
+
if (index !== -1) {
|
|
81
|
+
cbList.splice(index, 1);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
cbList.length = 0;
|
|
86
|
+
}
|
|
87
|
+
this.eventMap.set(type, cbList);
|
|
88
|
+
}
|
|
89
|
+
once(type, cb) {
|
|
90
|
+
ensureType(type);
|
|
91
|
+
const callback = (...args) => {
|
|
92
|
+
cb(...args);
|
|
93
|
+
this.off(type, callback);
|
|
94
|
+
};
|
|
95
|
+
this.on(type, callback);
|
|
96
|
+
}
|
|
97
|
+
send(type, payload) {
|
|
98
|
+
const data = {
|
|
99
|
+
id: this.id,
|
|
100
|
+
type,
|
|
101
|
+
payload,
|
|
102
|
+
};
|
|
103
|
+
if (this.type === 'server') {
|
|
104
|
+
const iframeList = [...document.querySelectorAll(`iframe[data-id="${this.id}"]`)];
|
|
105
|
+
iframeList.forEach((iframeItem) => {
|
|
106
|
+
iframeItem.contentWindow.postMessage(data, '*');
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
window.parent.postMessage(data, '*');
|
|
111
|
+
}
|
|
112
|
+
// v1 message
|
|
113
|
+
this.bc.postMessage(data);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
exports.Message = Message;
|
|
117
|
+
const messageCache = new Map();
|
|
118
|
+
function useMessage(id, type = 'client') {
|
|
119
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
120
|
+
const _id = id || window.frameElement?.dataset.id || window.name;
|
|
121
|
+
if (messageCache.has(_id)) {
|
|
122
|
+
return messageCache.get(_id);
|
|
123
|
+
}
|
|
124
|
+
const isInIframe = window !== window.parent;
|
|
125
|
+
const message = (type === 'server' || isInIframe) && _id ? new Message(_id, type) : null;
|
|
126
|
+
const data = { message };
|
|
127
|
+
messageCache.set(_id, data);
|
|
128
|
+
return data;
|
|
129
|
+
}
|
|
130
|
+
exports.useMessage = useMessage;
|
|
131
|
+
exports.default = {
|
|
132
|
+
useMessage,
|
|
133
|
+
Message,
|
|
134
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.generateBlockletEmbed = exports.getBlockletEmbedFromUrl = void 0;
|
|
7
|
+
const path_1 = require("path");
|
|
8
|
+
const jsdom_1 = __importDefault(require("jsdom"));
|
|
9
|
+
const lodash_1 = require("lodash");
|
|
10
|
+
const ufo_1 = require("ufo");
|
|
11
|
+
const axios_1 = __importDefault(require("axios"));
|
|
12
|
+
const { JSDOM } = jsdom_1.default;
|
|
13
|
+
const api = axios_1.default.create();
|
|
14
|
+
/**
|
|
15
|
+
* 判断 document 是否为开发环境
|
|
16
|
+
* @param document html document 对象(jsdom)
|
|
17
|
+
* @returns boolean
|
|
18
|
+
*/
|
|
19
|
+
function checkDev(document) {
|
|
20
|
+
const scirptList = document.querySelectorAll('script[type="module"]');
|
|
21
|
+
return !![...scirptList].find((scriptItem) => scriptItem.textContent?.includes('window.__vite_plugin_react_preamble_installed__ = true'));
|
|
22
|
+
}
|
|
23
|
+
async function getEmbedUrlFromUrl(url) {
|
|
24
|
+
try {
|
|
25
|
+
const { data: htmlContent } = await api.get(url, {
|
|
26
|
+
headers: {
|
|
27
|
+
accept: 'text/html,application/xhtml+xml,application/xml',
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
const { document } = new JSDOM(htmlContent).window;
|
|
31
|
+
let prefix = '/';
|
|
32
|
+
let metaUrl = url;
|
|
33
|
+
const link = document.querySelector('link[rel="blocklet-open-embed"]');
|
|
34
|
+
const blockletScript = document.querySelector('script[src="__blocklet__.js"]');
|
|
35
|
+
if (link) {
|
|
36
|
+
metaUrl = link.getAttribute('href') || url;
|
|
37
|
+
}
|
|
38
|
+
const isDev = checkDev(document);
|
|
39
|
+
if (blockletScript) {
|
|
40
|
+
const scriptUrl = new URL('__blocklet__.js?type=json', (0, ufo_1.withTrailingSlash)(url));
|
|
41
|
+
const { data: blockletMeta } = await api.get(scriptUrl.href);
|
|
42
|
+
prefix = blockletMeta.prefix;
|
|
43
|
+
}
|
|
44
|
+
return isDev ? (0, ufo_1.joinURL)(prefix, metaUrl.replace(prefix, '')) : (0, ufo_1.joinURL)(prefix, metaUrl);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return url;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
async function getBlockletEmbedFromUrl(url) {
|
|
51
|
+
const metaUrl = await getEmbedUrlFromUrl(url);
|
|
52
|
+
if (metaUrl) {
|
|
53
|
+
let finalUrl = '';
|
|
54
|
+
if (metaUrl.startsWith('http://') || metaUrl.startsWith('https://')) {
|
|
55
|
+
finalUrl = metaUrl;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
finalUrl = `${new URL(url).origin}${(0, path_1.join)('/', metaUrl)}`;
|
|
59
|
+
}
|
|
60
|
+
const { data: metaData } = await api.get(finalUrl);
|
|
61
|
+
if ((0, lodash_1.isObject)(metaData)) {
|
|
62
|
+
return metaData;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
exports.getBlockletEmbedFromUrl = getBlockletEmbedFromUrl;
|
|
68
|
+
function safeJsonParse(input, defaultValue) {
|
|
69
|
+
try {
|
|
70
|
+
return JSON.parse(input);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return defaultValue;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function generateBlockletEmbed() {
|
|
77
|
+
const BLOCKLET_MOUNT_POINTS = safeJsonParse(process.env.BLOCKLET_MOUNT_POINTS, []);
|
|
78
|
+
const { BLOCKLET_APP_NAME, BLOCKLET_APP_URL, BLOCKLET_REAL_NAME } = process.env;
|
|
79
|
+
let name = BLOCKLET_APP_NAME;
|
|
80
|
+
const blockletNames = BLOCKLET_REAL_NAME.split('/');
|
|
81
|
+
let url = '/';
|
|
82
|
+
const componentBlocklet = BLOCKLET_MOUNT_POINTS.find((blockletItem) => blockletItem.name === blockletNames[blockletNames.length - 1]);
|
|
83
|
+
if (componentBlocklet) {
|
|
84
|
+
// 先假设只有一层 component blocklet
|
|
85
|
+
url = componentBlocklet.mountPoint;
|
|
86
|
+
name = componentBlocklet.title;
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
name,
|
|
90
|
+
url,
|
|
91
|
+
origin: BLOCKLET_APP_URL,
|
|
92
|
+
embed: [],
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
exports.generateBlockletEmbed = generateBlockletEmbed;
|
|
@@ -1,3 +1,8 @@
|
|
|
1
1
|
import { NextFunction, Request, Response } from 'express';
|
|
2
|
-
|
|
2
|
+
type MiddlewareParams = {
|
|
3
|
+
roles?: string[];
|
|
4
|
+
permissions?: string[];
|
|
5
|
+
getClient?: Function;
|
|
6
|
+
};
|
|
7
|
+
declare const AuthMiddleware: ({ roles, permissions, getClient }?: MiddlewareParams) => (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
3
8
|
export = AuthMiddleware;
|
package/lib/middlewares/auth.js
CHANGED
|
@@ -1,41 +1,38 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
14
5
|
const lru_cache_1 = __importDefault(require("lru-cache"));
|
|
15
6
|
const auth_1 = __importDefault(require("../service/auth"));
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
7
|
+
const cache = new lru_cache_1.default({ max: 10, maxAge: 60 * 1000 });
|
|
8
|
+
const clients = {};
|
|
9
|
+
const getServiceClient = () => {
|
|
10
|
+
const appId = process.env.BLOCKLET_APP_ID;
|
|
11
|
+
if (!clients[appId]) {
|
|
12
|
+
clients[appId] = new auth_1.default();
|
|
13
|
+
}
|
|
14
|
+
return clients[appId];
|
|
15
|
+
};
|
|
16
|
+
const getPermissionsByRole = async (getClient, role) => {
|
|
17
|
+
if (!role) {
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
const cached = cache.get(role);
|
|
22
21
|
if (cached) {
|
|
23
22
|
return cached;
|
|
24
23
|
}
|
|
25
|
-
const res =
|
|
26
|
-
|
|
24
|
+
const res = await getClient().getPermissionsByRole(role);
|
|
25
|
+
cache.set(role, res);
|
|
27
26
|
return res;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const AuthMiddleware = ({ roles, permissions, _AuthClient = auth_1.default } = {}) => {
|
|
27
|
+
};
|
|
28
|
+
const AuthMiddleware = ({ roles, permissions, getClient = getServiceClient } = {}) => {
|
|
31
29
|
if (roles && !Array.isArray(roles)) {
|
|
32
30
|
throw new Error('roles must be array');
|
|
33
31
|
}
|
|
34
32
|
if (permissions && !Array.isArray(permissions)) {
|
|
35
33
|
throw new Error('permissions must be array');
|
|
36
34
|
}
|
|
37
|
-
|
|
38
|
-
return (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
|
|
35
|
+
return async (req, res, next) => {
|
|
39
36
|
if (!req.headers['x-user-did']) {
|
|
40
37
|
res.status(401).json({ code: 'forbidden', error: 'not authorized' });
|
|
41
38
|
return;
|
|
@@ -45,13 +42,13 @@ const AuthMiddleware = ({ roles, permissions, _AuthClient = auth_1.default } = {
|
|
|
45
42
|
return;
|
|
46
43
|
}
|
|
47
44
|
if (permissions) {
|
|
48
|
-
const { permissions: list } =
|
|
45
|
+
const { permissions: list } = await getPermissionsByRole(getClient, req.headers['x-user-role']);
|
|
49
46
|
if (!permissions.some((x) => (list || []).some((y) => y.name === x))) {
|
|
50
47
|
res.status(403).json({ code: 'forbidden', error: 'no permission' });
|
|
51
48
|
return;
|
|
52
49
|
}
|
|
53
50
|
}
|
|
54
51
|
next();
|
|
55
|
-
}
|
|
52
|
+
};
|
|
56
53
|
};
|
|
57
54
|
module.exports = AuthMiddleware;
|
|
@@ -12,7 +12,11 @@ declare const _default: {
|
|
|
12
12
|
fullName: string;
|
|
13
13
|
};
|
|
14
14
|
}, res: import("express").Response<any, Record<string, any>>, next: import("express").NextFunction) => Promise<void>;
|
|
15
|
-
auth: ({ roles, permissions,
|
|
15
|
+
auth: ({ roles, permissions, getClient }?: {
|
|
16
|
+
roles?: string[];
|
|
17
|
+
permissions?: string[];
|
|
18
|
+
getClient?: Function;
|
|
19
|
+
}) => (req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: import("express").Response<any, Record<string, any>>, next: import("express").NextFunction) => Promise<void>;
|
|
16
20
|
component: {
|
|
17
21
|
verifySig: (req: import("express").Request<import("express-serve-static-core").ParamsDictionary, any, any, import("qs").ParsedQs, Record<string, any>>, res: import("express").Response<any, Record<string, any>>, next: import("express").NextFunction) => void | import("express").Response<any, Record<string, any>>;
|
|
18
22
|
};
|
package/lib/middlewares/user.js
CHANGED
|
@@ -1,14 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
const userMiddleware = () => (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
|
|
2
|
+
const userMiddleware = () => async (req, res, next) => {
|
|
12
3
|
if (req.headers['x-user-did']) {
|
|
13
4
|
req.user = {
|
|
14
5
|
did: req.headers['x-user-did'],
|
|
@@ -17,5 +8,5 @@ const userMiddleware = () => (req, res, next) => __awaiter(void 0, void 0, void
|
|
|
17
8
|
};
|
|
18
9
|
}
|
|
19
10
|
next();
|
|
20
|
-
}
|
|
11
|
+
};
|
|
21
12
|
module.exports = userMiddleware;
|
package/lib/service/auth.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ interface AuthService {
|
|
|
22
22
|
grantPermissionForRole(role: string, permission: string): Promise<Client.GeneralResponse>;
|
|
23
23
|
revokePermissionFromRole(role: string, permission: string): Promise<Client.GeneralResponse>;
|
|
24
24
|
updatePermissionsForRole(role: string, permissions: string): Promise<Client.ResponseRole>;
|
|
25
|
-
hasPermission(role: string, permission: string): Promise<
|
|
25
|
+
hasPermission(role: string, permission: string): Promise<Client.BooleanResponse>;
|
|
26
26
|
getPermissions(): Promise<Client.ResponsePermissions>;
|
|
27
27
|
createPermission(args: OmitTeamDid<Client.RequestCreatePermissionInput>): Promise<Client.ResponsePermission>;
|
|
28
28
|
updatePermission(args: OmitTeamDid<Client.PermissionInput>): Promise<Client.ResponsePermission>;
|
package/lib/service/auth.js
CHANGED
|
@@ -1,13 +1,4 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
2
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
4
|
};
|
|
@@ -28,7 +19,7 @@ const type = process.env.BLOCKLET_WALLET_TYPE !== 'eth'
|
|
|
28
19
|
? (0, wallet_1.WalletType)({ role: mcrypto_1.types.RoleType.ROLE_APPLICATION, pk: mcrypto_1.types.KeyType.ED25519, hash: mcrypto_1.types.HashType.SHA3 })
|
|
29
20
|
: 'eth';
|
|
30
21
|
const fixAvatar = (user) => {
|
|
31
|
-
const avatar = user
|
|
22
|
+
const avatar = user?.avatar;
|
|
32
23
|
if (avatar && avatar.startsWith(USER_AVATAR_URL_PREFIX)) {
|
|
33
24
|
user.avatar = (0, url_join_1.default)(WELLKNOWN_SERVICE_PATH_PREFIX, USER_AVATAR_PATH_PREFIX, avatar.replace(USER_AVATAR_URL_PREFIX, ''));
|
|
34
25
|
}
|
|
@@ -97,30 +88,30 @@ class AuthService {
|
|
|
97
88
|
// 'configTrustedPassports',
|
|
98
89
|
];
|
|
99
90
|
const teamDid = process.env.BLOCKLET_DID;
|
|
100
|
-
const apiFallback = (fn) => (params = {}, ...args) => fn(
|
|
91
|
+
const apiFallback = (fn) => (params = {}, ...args) => fn({ input: { ...params, teamDid }, ...args });
|
|
101
92
|
// const apiConvertDid = (fn: Function) => (did: string) => fn({ input: { user: { did }, teamDid } });
|
|
102
93
|
const apiFnMap = {
|
|
103
|
-
getUser: (fn) => (did) =>
|
|
104
|
-
const res =
|
|
94
|
+
getUser: (fn) => async (did) => {
|
|
95
|
+
const res = await fn({ input: { user: { did }, teamDid } });
|
|
105
96
|
fixAvatar(res.user);
|
|
106
97
|
return res;
|
|
107
|
-
}
|
|
108
|
-
getUsers: (fn) => (args) =>
|
|
109
|
-
const res =
|
|
98
|
+
},
|
|
99
|
+
getUsers: (fn) => async (args) => {
|
|
100
|
+
const res = await fn({ input: { teamDid, ...args } });
|
|
110
101
|
(res.users || []).forEach(fixAvatar);
|
|
111
102
|
return res;
|
|
112
|
-
}
|
|
103
|
+
},
|
|
113
104
|
// removeUser: apiConvertDid,
|
|
114
105
|
// updateUserRole: (fn: Function) => (did: string, role: string) => fn({ input: { user: { did, role }, teamDid } }),
|
|
115
106
|
updateUserApproval: (fn) => (did, approved) => fn({ input: { user: { did, approved }, teamDid } }),
|
|
116
107
|
getPermissionsByRole: (fn) => (name) => fn({ input: { role: { name }, teamDid } }),
|
|
117
|
-
createRole: (fn) => ({ name, title, description }) => fn({ input:
|
|
108
|
+
createRole: (fn) => ({ name, title, description }) => fn({ input: { ...(0, pickBy_1.default)({ name, title, description }, isNotNullOrUndefined), teamDid } }),
|
|
118
109
|
updateRole: (fn) => (name, { title, description }) => fn({ input: { role: (0, pickBy_1.default)({ name, title, description }, isNotNullOrUndefined), teamDid } }),
|
|
119
110
|
deleteRole: (fn) => (name) => fn({ input: { name, teamDid } }),
|
|
120
111
|
grantPermissionForRole: (fn) => (roleName, permissionName) => fn({ input: { teamDid, roleName, grantName: permissionName } }),
|
|
121
112
|
revokePermissionFromRole: (fn) => (roleName, permissionName) => fn({ input: { teamDid, roleName, grantName: permissionName } }),
|
|
122
113
|
updatePermissionsForRole: (fn) => (roleName, permissionNames) => fn({ input: { teamDid, roleName, grantNames: permissionNames } }),
|
|
123
|
-
createPermission: (fn) => ({ name, description }) => fn({ input:
|
|
114
|
+
createPermission: (fn) => ({ name, description }) => fn({ input: { ...(0, pickBy_1.default)({ name, description }, isNotNullOrUndefined), teamDid } }),
|
|
124
115
|
updatePermission: (fn) => (name, { description }) => fn({ input: { permission: (0, pickBy_1.default)({ name, description }, isNotNullOrUndefined), teamDid } }),
|
|
125
116
|
deletePermission: (fn) => (name) => fn({ input: { name, teamDid } }),
|
|
126
117
|
hasPermission: (fn) => (role, permission) => fn({ input: { teamDid, role, permission } }),
|
|
@@ -11,6 +11,7 @@ type $TSFixMe = any;
|
|
|
11
11
|
* @returns
|
|
12
12
|
*/
|
|
13
13
|
declare const doSendToUser: (receiver: string | string[], notification: TNotificationInput, options?: TSendOptions) => Promise<any>;
|
|
14
|
+
declare const doSendToRelay: (topic: string, event: string, data: any) => Promise<any>;
|
|
14
15
|
/**
|
|
15
16
|
*
|
|
16
17
|
* @param {Notification} notification
|
|
@@ -30,9 +31,11 @@ export declare const _message: {
|
|
|
30
31
|
off: any;
|
|
31
32
|
};
|
|
32
33
|
export { doSendToUser as sendToUser };
|
|
34
|
+
export { doSendToRelay as sendToRelay };
|
|
33
35
|
export { broadcast };
|
|
34
36
|
declare const _default: {
|
|
35
37
|
sendToUser: (receiver: string | string[], notification: TNotificationInput, options?: TSendOptions) => Promise<any>;
|
|
38
|
+
sendToRelay: (topic: string, event: string, data: any) => Promise<any>;
|
|
36
39
|
broadcast: (notification: TNotificationInput, options?: TSendOptions) => Promise<any>;
|
|
37
40
|
on: (event: string, cb?: any) => EventEmitter;
|
|
38
41
|
off: any;
|
|
@@ -22,20 +22,11 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
-
});
|
|
33
|
-
};
|
|
34
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
27
|
};
|
|
37
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
-
exports.broadcast = exports.sendToUser = exports._message = exports.off = exports.on = void 0;
|
|
29
|
+
exports.broadcast = exports.sendToRelay = exports.sendToUser = exports._message = exports.off = exports.on = void 0;
|
|
39
30
|
/* eslint-disable @typescript-eslint/naming-convention */
|
|
40
31
|
const Jwt = __importStar(require("@arcblock/jwt"));
|
|
41
32
|
const events_1 = __importDefault(require("events"));
|
|
@@ -58,11 +49,16 @@ const getSender = () => ({
|
|
|
58
49
|
* }} options
|
|
59
50
|
* @returns
|
|
60
51
|
*/
|
|
61
|
-
const doSendToUser = (receiver, notification, options) =>
|
|
52
|
+
const doSendToUser = async (receiver, notification, options) => {
|
|
62
53
|
(0, check_blocklet_env_1.default)();
|
|
63
54
|
return (0, send_notification_1.sendToUser)(receiver, notification, getSender(), process.env.ABT_NODE_SERVICE_PORT, options);
|
|
64
|
-
}
|
|
55
|
+
};
|
|
65
56
|
exports.sendToUser = doSendToUser;
|
|
57
|
+
const doSendToRelay = async (topic, event, data) => {
|
|
58
|
+
(0, check_blocklet_env_1.default)();
|
|
59
|
+
return (0, send_notification_1.sendToRelay)(topic, event, data, getSender(), process.env.ABT_NODE_SERVICE_PORT);
|
|
60
|
+
};
|
|
61
|
+
exports.sendToRelay = doSendToRelay;
|
|
66
62
|
/**
|
|
67
63
|
*
|
|
68
64
|
* @param {Notification} notification
|
|
@@ -74,13 +70,13 @@ exports.sendToUser = doSendToUser;
|
|
|
74
70
|
* }} options
|
|
75
71
|
* @returns
|
|
76
72
|
*/
|
|
77
|
-
const broadcast = (notification, options = {}) =>
|
|
73
|
+
const broadcast = async (notification, options = {}) => {
|
|
78
74
|
(0, check_blocklet_env_1.default)();
|
|
79
75
|
const sender = getSender();
|
|
80
76
|
const { channel = (0, channel_1.getAppPublicChannel)(sender.appDid) } = options;
|
|
81
77
|
const { event = 'message' } = options;
|
|
82
78
|
return (0, send_notification_1.sendToAppChannel)(channel, event, notification, sender, process.env.ABT_NODE_SERVICE_PORT, options);
|
|
83
|
-
}
|
|
79
|
+
};
|
|
84
80
|
exports.broadcast = broadcast;
|
|
85
81
|
const emitter = new events_1.default();
|
|
86
82
|
const messageEmitter = new events_1.default();
|
|
@@ -178,6 +174,7 @@ exports._message = {
|
|
|
178
174
|
};
|
|
179
175
|
exports.default = {
|
|
180
176
|
sendToUser: doSendToUser,
|
|
177
|
+
sendToRelay: doSendToRelay,
|
|
181
178
|
broadcast,
|
|
182
179
|
on: exports.on,
|
|
183
180
|
off: exports.off,
|
package/lib/util/env.js
CHANGED
|
@@ -16,10 +16,11 @@ export type TNotificationSender = {
|
|
|
16
16
|
*/
|
|
17
17
|
declare const sendToUser: (receiver: string | string[], notification: TNotificationInput, { appDid, appSk }: TNotificationSender, port?: string, options?: {}) => Promise<any>;
|
|
18
18
|
declare const sendToAppChannel: (channel: string, event: string, notification: TNotificationInput, { appDid, appSk }: TNotificationSender, port?: string, options?: TSendOptions) => Promise<any>;
|
|
19
|
-
|
|
20
|
-
export { sendToAppChannel };
|
|
19
|
+
declare const sendToRelay: (topic: string, event: string, data: any, { appDid, appSk }: TNotificationSender, port?: string) => Promise<any>;
|
|
20
|
+
export { sendToUser, sendToAppChannel, sendToRelay };
|
|
21
21
|
declare const _default: {
|
|
22
22
|
sendToUser: (receiver: string | string[], notification: TNotificationInput, { appDid, appSk }: TNotificationSender, port?: string, options?: {}) => Promise<any>;
|
|
23
23
|
sendToAppChannel: (channel: string, event: string, notification: TNotificationInput, { appDid, appSk }: TNotificationSender, port?: string, options?: TSendOptions) => Promise<any>;
|
|
24
|
+
sendToRelay: (topic: string, event: string, data: any, { appDid, appSk }: TNotificationSender, port?: string) => Promise<any>;
|
|
24
25
|
};
|
|
25
26
|
export default _default;
|
|
@@ -22,24 +22,16 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
-
});
|
|
33
|
-
};
|
|
34
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
27
|
};
|
|
37
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
-
exports.sendToAppChannel = exports.sendToUser = void 0;
|
|
29
|
+
exports.sendToRelay = exports.sendToAppChannel = exports.sendToUser = void 0;
|
|
39
30
|
const axios_1 = __importDefault(require("axios"));
|
|
40
31
|
const pick_1 = __importDefault(require("lodash/pick"));
|
|
41
32
|
const JWT = __importStar(require("@arcblock/jwt"));
|
|
42
33
|
const constant_1 = __importDefault(require("@abtnode/constant"));
|
|
34
|
+
const channel_1 = require("@blocklet/meta/lib/channel");
|
|
43
35
|
const index_1 = require("../validators/index");
|
|
44
36
|
const constants_1 = require("./constants");
|
|
45
37
|
const version_1 = require("../version");
|
|
@@ -59,15 +51,15 @@ const getRequestHeaders = () => ({ 'User-Agent': `BlockletSDK/${VERSION}` });
|
|
|
59
51
|
* @param {Object} options
|
|
60
52
|
* @returns
|
|
61
53
|
*/
|
|
62
|
-
const sendToUser = (receiver, notification, { appDid, appSk }, port = process.env.ABT_NODE_SERVICE_PORT, options = {}) =>
|
|
63
|
-
|
|
54
|
+
const sendToUser = async (receiver, notification, { appDid, appSk }, port = process.env.ABT_NODE_SERVICE_PORT, options = {}) => {
|
|
55
|
+
await (0, index_1.validateReceiver)(receiver);
|
|
64
56
|
const opt = (0, pick_1.default)(options, ['keepForOfflineUser']);
|
|
65
|
-
|
|
57
|
+
await (0, index_1.validateOption)(opt);
|
|
66
58
|
if (SERVER_MODE !== NODE_MODES.DEBUG) {
|
|
67
|
-
|
|
59
|
+
await (0, index_1.validateNotification)(notification);
|
|
68
60
|
}
|
|
69
61
|
try {
|
|
70
|
-
const { data: res } =
|
|
62
|
+
const { data: res } = await axios.post(`http://127.0.0.1:${port}${constants_1.SERVICE_PREFIX}/api/send-to-user`, {
|
|
71
63
|
apiVersion: VERSION,
|
|
72
64
|
data: {
|
|
73
65
|
sender: { appDid, token: JWT.sign(appDid, appSk) },
|
|
@@ -85,16 +77,16 @@ const sendToUser = (receiver, notification, { appDid, appSk }, port = process.en
|
|
|
85
77
|
console.error(err.response ? err.response.data : err);
|
|
86
78
|
throw new Error(err.response ? err.response.data : err.message);
|
|
87
79
|
}
|
|
88
|
-
}
|
|
80
|
+
};
|
|
89
81
|
exports.sendToUser = sendToUser;
|
|
90
|
-
const sendToAppChannel = (channel, event, notification, { appDid, appSk }, port = process.env.ABT_NODE_SERVICE_PORT, options = {}) =>
|
|
82
|
+
const sendToAppChannel = async (channel, event, notification, { appDid, appSk }, port = process.env.ABT_NODE_SERVICE_PORT, options = {}) => {
|
|
91
83
|
if (!channel) {
|
|
92
84
|
throw new Error('channel is required');
|
|
93
85
|
}
|
|
94
86
|
if (!event) {
|
|
95
87
|
throw new Error('event is required');
|
|
96
88
|
}
|
|
97
|
-
|
|
89
|
+
await (0, index_1.validateChannelEvent)(event);
|
|
98
90
|
const opt = (0, pick_1.default)(options, ['socketId', 'userDid']);
|
|
99
91
|
if (opt.userDid) {
|
|
100
92
|
// @ts-expect-error TS(2551) FIXME: Property 'socketDid' does not exist on type 'Pick<... Remove this comment to see the full error message
|
|
@@ -102,10 +94,10 @@ const sendToAppChannel = (channel, event, notification, { appDid, appSk }, port
|
|
|
102
94
|
delete opt.userDid;
|
|
103
95
|
}
|
|
104
96
|
if (SERVER_MODE !== NODE_MODES.DEBUG) {
|
|
105
|
-
|
|
97
|
+
await (0, index_1.validateNotification)(notification);
|
|
106
98
|
}
|
|
107
99
|
try {
|
|
108
|
-
const { data: res } =
|
|
100
|
+
const { data: res } = await axios.post(`http://127.0.0.1:${port}${constants_1.SERVICE_PREFIX}/api/send-to-app-channel`, {
|
|
109
101
|
apiVersion: VERSION,
|
|
110
102
|
data: {
|
|
111
103
|
sender: { appDid, token: JWT.sign(appDid, appSk) },
|
|
@@ -124,9 +116,41 @@ const sendToAppChannel = (channel, event, notification, { appDid, appSk }, port
|
|
|
124
116
|
console.error(err.response ? err.response.data : err);
|
|
125
117
|
throw new Error(err.response ? err.response.data : err.message);
|
|
126
118
|
}
|
|
127
|
-
}
|
|
119
|
+
};
|
|
128
120
|
exports.sendToAppChannel = sendToAppChannel;
|
|
121
|
+
const sendToRelay = async (topic, event, data, { appDid, appSk }, port = process.env.ABT_NODE_SERVICE_PORT) => {
|
|
122
|
+
if (!topic) {
|
|
123
|
+
throw new Error('topic is required');
|
|
124
|
+
}
|
|
125
|
+
if (!event) {
|
|
126
|
+
throw new Error('event is required');
|
|
127
|
+
}
|
|
128
|
+
if (!data) {
|
|
129
|
+
throw new Error('data is required');
|
|
130
|
+
}
|
|
131
|
+
try {
|
|
132
|
+
const { data: res } = await axios.post(`http://127.0.0.1:${port}${constants_1.SERVICE_PREFIX}/relay/api/send-to-relay-channel`, {
|
|
133
|
+
apiVersion: VERSION,
|
|
134
|
+
data: {
|
|
135
|
+
sender: { appDid, token: JWT.sign(appDid, appSk) },
|
|
136
|
+
channel: (0, channel_1.getRelayChannel)(appDid, topic),
|
|
137
|
+
event,
|
|
138
|
+
data,
|
|
139
|
+
},
|
|
140
|
+
}, {
|
|
141
|
+
timeout: 60 * 1000,
|
|
142
|
+
headers: getRequestHeaders(),
|
|
143
|
+
});
|
|
144
|
+
return res;
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
console.error(err.response ? err.response.data : err);
|
|
148
|
+
throw new Error(err.response ? err.response.data : err.message);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
exports.sendToRelay = sendToRelay;
|
|
129
152
|
exports.default = {
|
|
130
153
|
sendToUser,
|
|
131
154
|
sendToAppChannel,
|
|
155
|
+
sendToRelay,
|
|
132
156
|
};
|
package/lib/version.d.ts
CHANGED
package/lib/version.js
CHANGED
|
@@ -9,7 +9,10 @@ const shared_1 = __importDefault(require("./connect/shared"));
|
|
|
9
9
|
class WalletAuthenticator extends did_auth_1.WalletAuthenticator {
|
|
10
10
|
constructor(options = {}) {
|
|
11
11
|
(0, check_blocklet_env_1.default)();
|
|
12
|
-
super(
|
|
12
|
+
super({
|
|
13
|
+
wallet: (0, wallet_1.default)().toJSON(),
|
|
14
|
+
...(0, shared_1.default)(options),
|
|
15
|
+
});
|
|
13
16
|
}
|
|
14
17
|
}
|
|
15
18
|
module.exports = WalletAuthenticator;
|
package/lib/wallet-handler.d.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { WalletHandlers as Handler } from '@arcblock/did-auth';
|
|
2
2
|
declare class WalletHandlers extends Handler {
|
|
3
3
|
enableConnect: boolean;
|
|
4
|
-
sendNotificationFn:
|
|
4
|
+
sendNotificationFn: Function;
|
|
5
|
+
sendToRelayFn: Function;
|
|
5
6
|
/**
|
|
6
|
-
* @param {boolean} autoConnect enable auto connect to wallet (wallet does not need to scan qr code)
|
|
7
|
-
* @param {boolean} connectedDidOnly only current login did or connected did can connect
|
|
8
|
-
* @param {function} sendNotificationFn use in a non-blocklet environment
|
|
7
|
+
* @param {boolean} params.autoConnect enable auto connect to wallet (wallet does not need to scan qr code)
|
|
8
|
+
* @param {boolean} params.connectedDidOnly only current login did or connected did can connect
|
|
9
|
+
* @param {function} [params.sendNotificationFn] use in a non-blocklet environment
|
|
10
|
+
* @param {function} [params.sendToRelayFn]
|
|
9
11
|
*/
|
|
10
|
-
constructor({ autoConnect, connectedDidOnly, sendNotificationFn, options, ...opts }:
|
|
12
|
+
constructor({ autoConnect, connectedDidOnly, sendNotificationFn, sendToRelayFn, options, ...opts }: any);
|
|
11
13
|
getConnectedDid: ({ req, didwallet, extraParams }: $TSFixMe) => any;
|
|
12
14
|
attach({ onStart, ...opts }: {
|
|
13
15
|
[x: string]: any;
|
package/lib/wallet-handler.js
CHANGED
|
@@ -22,26 +22,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
-
});
|
|
33
|
-
};
|
|
34
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
35
|
-
var t = {};
|
|
36
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
37
|
-
t[p] = s[p];
|
|
38
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
39
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
40
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
41
|
-
t[p[i]] = s[p[i]];
|
|
42
|
-
}
|
|
43
|
-
return t;
|
|
44
|
-
};
|
|
45
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
46
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
47
27
|
};
|
|
@@ -56,19 +36,21 @@ const inMobileWallet = (didwallet) => {
|
|
|
56
36
|
};
|
|
57
37
|
class WalletHandlers extends did_auth_1.WalletHandlers {
|
|
58
38
|
/**
|
|
59
|
-
* @param {boolean} autoConnect enable auto connect to wallet (wallet does not need to scan qr code)
|
|
60
|
-
* @param {boolean} connectedDidOnly only current login did or connected did can connect
|
|
61
|
-
* @param {function} sendNotificationFn use in a non-blocklet environment
|
|
39
|
+
* @param {boolean} params.autoConnect enable auto connect to wallet (wallet does not need to scan qr code)
|
|
40
|
+
* @param {boolean} params.connectedDidOnly only current login did or connected did can connect
|
|
41
|
+
* @param {function} [params.sendNotificationFn] use in a non-blocklet environment
|
|
42
|
+
* @param {function} [params.sendToRelayFn]
|
|
62
43
|
*/
|
|
63
|
-
constructor(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
44
|
+
constructor({ autoConnect = true, connectedDidOnly = false, sendNotificationFn = null, sendToRelayFn = null, options = {}, ...opts }) {
|
|
45
|
+
super({
|
|
46
|
+
options: {
|
|
47
|
+
...options,
|
|
48
|
+
...{
|
|
49
|
+
sessionDidKey: autoConnect && connectedDidOnly ? CONNECTED_DID_KEY : options?.sessionDidKey,
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
...opts,
|
|
53
|
+
});
|
|
72
54
|
this.getConnectedDid = ({ req, didwallet, extraParams }) => {
|
|
73
55
|
if (extraParams && extraParams.autoConnect === 'false') {
|
|
74
56
|
return null;
|
|
@@ -83,12 +65,16 @@ class WalletHandlers extends did_auth_1.WalletHandlers {
|
|
|
83
65
|
};
|
|
84
66
|
this.enableConnect = !!autoConnect;
|
|
85
67
|
this.sendNotificationFn = sendNotificationFn || notification_1.sendToUser.bind(notification_1.default);
|
|
68
|
+
this.sendToRelayFn = sendToRelayFn || notification_1.sendToRelay.bind(notification_1.default);
|
|
69
|
+
// @ts-ignore
|
|
70
|
+
this.on('updated', (session) => {
|
|
71
|
+
this.sendToRelayFn(session.token, 'updated', session).catch(console.error);
|
|
72
|
+
});
|
|
86
73
|
}
|
|
87
|
-
attach(
|
|
88
|
-
|
|
89
|
-
const realOnStart = (params) => __awaiter(this, void 0, void 0, function* () {
|
|
74
|
+
attach({ onStart = noop, ...opts }) {
|
|
75
|
+
const realOnStart = async (params) => {
|
|
90
76
|
// @ts-expect-error TS(2554) FIXME: Expected 0 arguments, but got 1.
|
|
91
|
-
const extra = (
|
|
77
|
+
const extra = (await onStart(params)) || {};
|
|
92
78
|
const connectedDid = this.getConnectedDid(params);
|
|
93
79
|
// fill extra
|
|
94
80
|
extra.connectedDid = connectedDid || '';
|
|
@@ -96,9 +82,8 @@ class WalletHandlers extends did_auth_1.WalletHandlers {
|
|
|
96
82
|
// send notification to wallet to trigger wallet to auto connect
|
|
97
83
|
if (connectedDid) {
|
|
98
84
|
// wallet use check url to check status of the session
|
|
99
|
-
let checkUrl
|
|
85
|
+
let checkUrl;
|
|
100
86
|
try {
|
|
101
|
-
// @ts-expect-error TS(2322) FIXME: Type 'URL' is not assignable to type 'string'.
|
|
102
87
|
checkUrl = new URL(decodeURIComponent(new URL(params.deepLink).searchParams.get('url')));
|
|
103
88
|
checkUrl.pathname = checkUrl.pathname.replace(/auth$/, 'status');
|
|
104
89
|
}
|
|
@@ -122,9 +107,12 @@ class WalletHandlers extends did_auth_1.WalletHandlers {
|
|
|
122
107
|
});
|
|
123
108
|
}
|
|
124
109
|
return extra;
|
|
125
|
-
}
|
|
110
|
+
};
|
|
126
111
|
// @ts-expect-error TS(2345) FIXME: Argument of type '{ onStart: (params: any) => Prom... Remove this comment to see the full error message
|
|
127
|
-
super.attach(
|
|
112
|
+
super.attach({
|
|
113
|
+
onStart: realOnStart,
|
|
114
|
+
...opts,
|
|
115
|
+
});
|
|
128
116
|
}
|
|
129
117
|
}
|
|
130
118
|
module.exports = WalletHandlers;
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.8.
|
|
6
|
+
"version": "1.8.67-beta-65933c91",
|
|
7
7
|
"description": "graphql client to read/write data on abt node",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"typings": "lib/index.d.ts",
|
|
@@ -28,22 +28,25 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@abtnode/client": "1.8.66",
|
|
30
30
|
"@abtnode/constant": "1.8.66",
|
|
31
|
-
"@
|
|
32
|
-
"@arcblock/
|
|
33
|
-
"@arcblock/
|
|
31
|
+
"@abtnode/util": "^1.8.66",
|
|
32
|
+
"@arcblock/did-auth": "1.18.56",
|
|
33
|
+
"@arcblock/jwt": "1.18.56",
|
|
34
|
+
"@arcblock/ws": "1.18.56",
|
|
34
35
|
"@blocklet/constant": "1.8.66",
|
|
35
36
|
"@blocklet/meta": "1.8.66",
|
|
36
|
-
"@did-connect/authenticator": "^2.1.
|
|
37
|
-
"@did-connect/handler": "^2.1.
|
|
37
|
+
"@did-connect/authenticator": "^2.1.40",
|
|
38
|
+
"@did-connect/handler": "^2.1.40",
|
|
38
39
|
"@nedb/core": "^2.1.5",
|
|
39
|
-
"@ocap/mcrypto": "1.18.
|
|
40
|
-
"@ocap/wallet": "1.18.
|
|
40
|
+
"@ocap/mcrypto": "1.18.56",
|
|
41
|
+
"@ocap/wallet": "1.18.56",
|
|
41
42
|
"axios": "^0.27.2",
|
|
42
43
|
"fs-extra": "^10.1.0",
|
|
43
44
|
"joi": "17.7.0",
|
|
45
|
+
"jsdom": "^21.1.0",
|
|
44
46
|
"json-stable-stringify": "^1.0.1",
|
|
45
47
|
"lodash": "^4.17.21",
|
|
46
48
|
"lru-cache": "^6.0.0",
|
|
49
|
+
"ufo": "^1.1.1",
|
|
47
50
|
"url-join": "^4.0.1"
|
|
48
51
|
},
|
|
49
52
|
"resolutions": {
|
|
@@ -61,12 +64,11 @@
|
|
|
61
64
|
"detect-port": "^1.5.1",
|
|
62
65
|
"eslint": "^8.25.0",
|
|
63
66
|
"jest": "^29.2.0",
|
|
64
|
-
"joi-to-typescript": "^4.0.
|
|
67
|
+
"joi-to-typescript": "^4.0.7",
|
|
65
68
|
"json-stable-stringify": "^1.0.1",
|
|
66
69
|
"prettier": "^2.7.1",
|
|
67
70
|
"ts-jest": "^29.0.3",
|
|
68
71
|
"ts-node": "^10.9.1",
|
|
69
72
|
"typescript": "^4.8.4"
|
|
70
|
-
}
|
|
71
|
-
"gitHead": "282247fd0ce6702e1d6920e90e2b3be0408cf879"
|
|
73
|
+
}
|
|
72
74
|
}
|