@nocobase/plugin-verification 0.7.5-alpha.1
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 +201 -0
- package/lib/Plugin.d.ts +21 -0
- package/lib/Plugin.js +216 -0
- package/lib/actions/index.d.ts +3 -0
- package/lib/actions/index.js +30 -0
- package/lib/actions/verifications.d.ts +2 -0
- package/lib/actions/verifications.js +195 -0
- package/lib/collections/verifications.d.ts +29 -0
- package/lib/collections/verifications.js +35 -0
- package/lib/collections/verifications_providers.d.ts +13 -0
- package/lib/collections/verifications_providers.js +24 -0
- package/lib/constants.d.ts +3 -0
- package/lib/constants.js +12 -0
- package/lib/index.d.ts +4 -0
- package/lib/index.js +46 -0
- package/lib/locale/index.d.ts +1 -0
- package/lib/locale/index.js +15 -0
- package/lib/locale/zh-CN.d.ts +7 -0
- package/lib/locale/zh-CN.js +13 -0
- package/lib/providers/index.d.ts +14 -0
- package/lib/providers/index.js +84 -0
- package/lib/providers/sms-aliyun.d.ts +7 -0
- package/lib/providers/sms-aliyun.js +111 -0
- package/package.json +25 -0
- package/src/Plugin.ts +141 -0
- package/src/__tests__/Plugin.test.ts +162 -0
- package/src/__tests__/collections/authors.ts +15 -0
- package/src/__tests__/index.ts +39 -0
- package/src/actions/index.ts +14 -0
- package/src/actions/verifications.ts +105 -0
- package/src/collections/verifications.ts +36 -0
- package/src/collections/verifications_providers.ts +22 -0
- package/src/constants.ts +4 -0
- package/src/index.ts +5 -0
- package/src/locale/index.ts +1 -0
- package/src/locale/zh-CN.ts +6 -0
- package/src/providers/index.ts +32 -0
- package/src/providers/sms-aliyun.ts +62 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
name: string;
|
|
3
|
+
fields: ({
|
|
4
|
+
type: string;
|
|
5
|
+
name: string;
|
|
6
|
+
primaryKey: boolean;
|
|
7
|
+
defaultValue?: undefined;
|
|
8
|
+
target?: undefined;
|
|
9
|
+
} | {
|
|
10
|
+
type: string;
|
|
11
|
+
name: string;
|
|
12
|
+
primaryKey?: undefined;
|
|
13
|
+
defaultValue?: undefined;
|
|
14
|
+
target?: undefined;
|
|
15
|
+
} | {
|
|
16
|
+
type: string;
|
|
17
|
+
name: string;
|
|
18
|
+
defaultValue: number;
|
|
19
|
+
primaryKey?: undefined;
|
|
20
|
+
target?: undefined;
|
|
21
|
+
} | {
|
|
22
|
+
type: string;
|
|
23
|
+
name: string;
|
|
24
|
+
target: string;
|
|
25
|
+
primaryKey?: undefined;
|
|
26
|
+
defaultValue?: undefined;
|
|
27
|
+
})[];
|
|
28
|
+
};
|
|
29
|
+
export default _default;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _default = {
|
|
8
|
+
name: 'verifications',
|
|
9
|
+
fields: [{
|
|
10
|
+
type: 'uuid',
|
|
11
|
+
name: 'id',
|
|
12
|
+
primaryKey: true
|
|
13
|
+
}, {
|
|
14
|
+
type: 'string',
|
|
15
|
+
name: 'type'
|
|
16
|
+
}, {
|
|
17
|
+
type: 'string',
|
|
18
|
+
name: 'receiver'
|
|
19
|
+
}, {
|
|
20
|
+
type: 'integer',
|
|
21
|
+
name: 'status',
|
|
22
|
+
defaultValue: 0
|
|
23
|
+
}, {
|
|
24
|
+
type: 'date',
|
|
25
|
+
name: 'expiresAt'
|
|
26
|
+
}, {
|
|
27
|
+
type: 'string',
|
|
28
|
+
name: 'content'
|
|
29
|
+
}, {
|
|
30
|
+
type: 'belongsTo',
|
|
31
|
+
name: 'provider',
|
|
32
|
+
target: 'verifications_providers'
|
|
33
|
+
}]
|
|
34
|
+
};
|
|
35
|
+
exports.default = _default;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _default = {
|
|
8
|
+
name: 'verifications_providers',
|
|
9
|
+
fields: [{
|
|
10
|
+
type: 'string',
|
|
11
|
+
name: 'id',
|
|
12
|
+
primaryKey: true
|
|
13
|
+
}, {
|
|
14
|
+
type: 'string',
|
|
15
|
+
name: 'title'
|
|
16
|
+
}, {
|
|
17
|
+
type: 'string',
|
|
18
|
+
name: 'type'
|
|
19
|
+
}, {
|
|
20
|
+
type: 'jsonb',
|
|
21
|
+
name: 'options'
|
|
22
|
+
}]
|
|
23
|
+
};
|
|
24
|
+
exports.default = _default;
|
package/lib/constants.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.PROVIDER_TYPE_SMS_ALIYUN = exports.CODE_STATUS_USED = exports.CODE_STATUS_UNUSED = void 0;
|
|
7
|
+
const PROVIDER_TYPE_SMS_ALIYUN = 'sms-aliyun';
|
|
8
|
+
exports.PROVIDER_TYPE_SMS_ALIYUN = PROVIDER_TYPE_SMS_ALIYUN;
|
|
9
|
+
const CODE_STATUS_UNUSED = 0;
|
|
10
|
+
exports.CODE_STATUS_UNUSED = CODE_STATUS_UNUSED;
|
|
11
|
+
const CODE_STATUS_USED = 1;
|
|
12
|
+
exports.CODE_STATUS_USED = CODE_STATUS_USED;
|
package/lib/index.d.ts
ADDED
package/lib/index.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
var _exportNames = {
|
|
7
|
+
namespace: true,
|
|
8
|
+
Provider: true
|
|
9
|
+
};
|
|
10
|
+
Object.defineProperty(exports, "Provider", {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
get: function get() {
|
|
13
|
+
return _providers.Provider;
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
Object.defineProperty(exports, "default", {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
get: function get() {
|
|
19
|
+
return _Plugin.default;
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
exports.namespace = void 0;
|
|
23
|
+
|
|
24
|
+
var _constants = require("./constants");
|
|
25
|
+
|
|
26
|
+
Object.keys(_constants).forEach(function (key) {
|
|
27
|
+
if (key === "default" || key === "__esModule") return;
|
|
28
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
29
|
+
if (key in exports && exports[key] === _constants[key]) return;
|
|
30
|
+
Object.defineProperty(exports, key, {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
get: function get() {
|
|
33
|
+
return _constants[key];
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
var _providers = require("./providers");
|
|
39
|
+
|
|
40
|
+
var _Plugin = _interopRequireDefault(require("./Plugin"));
|
|
41
|
+
|
|
42
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
43
|
+
|
|
44
|
+
const namespace = require('../package.json').name;
|
|
45
|
+
|
|
46
|
+
exports.namespace = namespace;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as zhCN } from './zh-CN';
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "zhCN", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function get() {
|
|
9
|
+
return _zhCN.default;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
var _zhCN = _interopRequireDefault(require("./zh-CN"));
|
|
14
|
+
|
|
15
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
declare const _default: {
|
|
2
|
+
'Verification send failed, please try later or contact to administrator': string;
|
|
3
|
+
'Not a valid cellphone number, please re-enter': string;
|
|
4
|
+
"Please don't retry in {{time}} seconds": string;
|
|
5
|
+
'You are trying so frequently, please slow down': string;
|
|
6
|
+
};
|
|
7
|
+
export default _default;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _default = {
|
|
8
|
+
'Verification send failed, please try later or contact to administrator': '验证码发送失败,请稍后重试或联系管理员',
|
|
9
|
+
'Not a valid cellphone number, please re-enter': '不是有效的手机号,请重新输入',
|
|
10
|
+
"Please don't retry in {{time}} seconds": '请 {{time}} 秒后再试',
|
|
11
|
+
'You are trying so frequently, please slow down': '您的操作太频繁,请稍后再试'
|
|
12
|
+
};
|
|
13
|
+
exports.default = _default;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import Plugin from '../Plugin';
|
|
2
|
+
export declare class Provider {
|
|
3
|
+
protected plugin: Plugin;
|
|
4
|
+
protected options: any;
|
|
5
|
+
constructor(plugin: Plugin, options: any);
|
|
6
|
+
send(receiver: string, data: {
|
|
7
|
+
[key: string]: any;
|
|
8
|
+
}): Promise<any>;
|
|
9
|
+
}
|
|
10
|
+
interface Providers {
|
|
11
|
+
[key: string]: typeof Provider;
|
|
12
|
+
}
|
|
13
|
+
export default function (plugin: Plugin, more?: Providers): void;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.Provider = void 0;
|
|
7
|
+
exports.default = _default;
|
|
8
|
+
|
|
9
|
+
function _path() {
|
|
10
|
+
const data = _interopRequireDefault(require("path"));
|
|
11
|
+
|
|
12
|
+
_path = function _path() {
|
|
13
|
+
return data;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
return data;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function _utils() {
|
|
20
|
+
const data = require("@nocobase/utils");
|
|
21
|
+
|
|
22
|
+
_utils = function _utils() {
|
|
23
|
+
return data;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
return data;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
var _constants = require("../constants");
|
|
30
|
+
|
|
31
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
32
|
+
|
|
33
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
34
|
+
|
|
35
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
36
|
+
|
|
37
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
38
|
+
|
|
39
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
40
|
+
|
|
41
|
+
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
42
|
+
|
|
43
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
44
|
+
|
|
45
|
+
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
46
|
+
|
|
47
|
+
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
|
|
48
|
+
|
|
49
|
+
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
50
|
+
|
|
51
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
52
|
+
|
|
53
|
+
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
54
|
+
|
|
55
|
+
class Provider {
|
|
56
|
+
constructor(plugin, options) {
|
|
57
|
+
this.plugin = void 0;
|
|
58
|
+
this.options = void 0;
|
|
59
|
+
this.plugin = plugin;
|
|
60
|
+
this.options = options;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
send(receiver, data) {
|
|
64
|
+
return _asyncToGenerator(function* () {})();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
exports.Provider = Provider;
|
|
70
|
+
|
|
71
|
+
function _default(plugin, more = {}) {
|
|
72
|
+
const providers = plugin.providers;
|
|
73
|
+
const natives = [_constants.PROVIDER_TYPE_SMS_ALIYUN].reduce((result, key) => Object.assign(result, {
|
|
74
|
+
[key]: (0, _utils().requireModule)(_path().default.isAbsolute(key) ? key : _path().default.join(__dirname, key))
|
|
75
|
+
}), {});
|
|
76
|
+
|
|
77
|
+
for (var _i = 0, _Object$entries = Object.entries(_objectSpread(_objectSpread({}, more), natives)); _i < _Object$entries.length; _i++) {
|
|
78
|
+
const _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
|
|
79
|
+
name = _Object$entries$_i[0],
|
|
80
|
+
provider = _Object$entries$_i[1];
|
|
81
|
+
|
|
82
|
+
providers.register(name, provider);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
function _dysmsapi() {
|
|
9
|
+
const data = _interopRequireWildcard(require("@alicloud/dysmsapi20170525"));
|
|
10
|
+
|
|
11
|
+
_dysmsapi = function _dysmsapi() {
|
|
12
|
+
return data;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
return data;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function OpenApi() {
|
|
19
|
+
const data = _interopRequireWildcard(require("@alicloud/openapi-client"));
|
|
20
|
+
|
|
21
|
+
OpenApi = function OpenApi() {
|
|
22
|
+
return data;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
return data;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function _teaUtil() {
|
|
29
|
+
const data = require("@alicloud/tea-util");
|
|
30
|
+
|
|
31
|
+
_teaUtil = function _teaUtil() {
|
|
32
|
+
return data;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
return data;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
var _ = require(".");
|
|
39
|
+
|
|
40
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
41
|
+
|
|
42
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
43
|
+
|
|
44
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
45
|
+
|
|
46
|
+
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
47
|
+
|
|
48
|
+
class _default extends _.Provider {
|
|
49
|
+
constructor(plugin, options) {
|
|
50
|
+
super(plugin, options);
|
|
51
|
+
this.client = void 0;
|
|
52
|
+
const _this$options = this.options,
|
|
53
|
+
accessKeyId = _this$options.accessKeyId,
|
|
54
|
+
accessKeySecret = _this$options.accessKeySecret,
|
|
55
|
+
endpoint = _this$options.endpoint;
|
|
56
|
+
let config = new (OpenApi().Config)({
|
|
57
|
+
// 您的 AccessKey ID
|
|
58
|
+
accessKeyId: accessKeyId,
|
|
59
|
+
// 您的 AccessKey Secret
|
|
60
|
+
accessKeySecret: accessKeySecret
|
|
61
|
+
}); // 访问的域名
|
|
62
|
+
|
|
63
|
+
config.endpoint = endpoint;
|
|
64
|
+
this.client = new (_dysmsapi().default)(config);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
send(phoneNumbers, data = {}) {
|
|
68
|
+
var _this = this;
|
|
69
|
+
|
|
70
|
+
return _asyncToGenerator(function* () {
|
|
71
|
+
const request = new (_dysmsapi().SendSmsRequest)({
|
|
72
|
+
phoneNumbers,
|
|
73
|
+
signName: _this.options.sign,
|
|
74
|
+
templateCode: _this.options.template,
|
|
75
|
+
templateParam: JSON.stringify(data)
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
try {
|
|
79
|
+
const _yield$_this$client$s = yield _this.client.sendSmsWithOptions(request, new (_teaUtil().RuntimeOptions)({})),
|
|
80
|
+
body = _yield$_this$client$s.body;
|
|
81
|
+
|
|
82
|
+
let err = new Error(body.message);
|
|
83
|
+
|
|
84
|
+
switch (body.code) {
|
|
85
|
+
case 'OK':
|
|
86
|
+
break;
|
|
87
|
+
|
|
88
|
+
case 'isv.MOBILE_NUMBER_ILLEGAL':
|
|
89
|
+
err.name = 'InvalidReceiver';
|
|
90
|
+
return Promise.reject(err);
|
|
91
|
+
|
|
92
|
+
case 'isv.BUSINESS_LIMIT_CONTROL':
|
|
93
|
+
err.name = 'RateLimit';
|
|
94
|
+
console.error(body);
|
|
95
|
+
return Promise.reject(err);
|
|
96
|
+
|
|
97
|
+
default:
|
|
98
|
+
// should not let user to know
|
|
99
|
+
console.error(body);
|
|
100
|
+
err.name = 'SendSMSFailed';
|
|
101
|
+
return Promise.reject(err);
|
|
102
|
+
}
|
|
103
|
+
} catch (error) {
|
|
104
|
+
return Promise.reject(error);
|
|
105
|
+
}
|
|
106
|
+
})();
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
exports.default = _default;
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nocobase/plugin-verification",
|
|
3
|
+
"version": "0.7.5-alpha.1",
|
|
4
|
+
"main": "lib/index.js",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"licenses": [
|
|
7
|
+
{
|
|
8
|
+
"type": "Apache-2.0",
|
|
9
|
+
"url": "http://www.apache.org/licenses/LICENSE-2.0"
|
|
10
|
+
}
|
|
11
|
+
],
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@alicloud/dysmsapi20170525": "2.0.17",
|
|
14
|
+
"@alicloud/openapi-client": "0.4.1",
|
|
15
|
+
"@alicloud/tea-util": "1.4.4",
|
|
16
|
+
"@nocobase/actions": "0.7.5-alpha.1",
|
|
17
|
+
"@nocobase/resourcer": "0.7.5-alpha.1",
|
|
18
|
+
"@nocobase/server": "0.7.5-alpha.1",
|
|
19
|
+
"@nocobase/utils": "0.7.5-alpha.1"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@nocobase/test": "0.7.5-alpha.1"
|
|
23
|
+
},
|
|
24
|
+
"gitHead": "f6eb27b68185bb0c0b4c2cfca1df84205a9b9173"
|
|
25
|
+
}
|
package/src/Plugin.ts
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
|
|
3
|
+
import { Plugin } from '@nocobase/server';
|
|
4
|
+
import { Registry } from '@nocobase/utils';
|
|
5
|
+
import { Op } from '@nocobase/database';
|
|
6
|
+
import { HandlerType } from '@nocobase/resourcer';
|
|
7
|
+
import { Context } from '@nocobase/actions';
|
|
8
|
+
|
|
9
|
+
import initProviders, { Provider } from './providers';
|
|
10
|
+
import initActions from './actions';
|
|
11
|
+
import { CODE_STATUS_UNUSED, CODE_STATUS_USED, PROVIDER_TYPE_SMS_ALIYUN } from './constants';
|
|
12
|
+
import { namespace } from '.';
|
|
13
|
+
import { zhCN } from './locale';
|
|
14
|
+
|
|
15
|
+
export interface Interceptor {
|
|
16
|
+
manual?: boolean;
|
|
17
|
+
provider: string;
|
|
18
|
+
expiresIn?: number;
|
|
19
|
+
getReceiver(ctx): string;
|
|
20
|
+
getCode?(ctx): string;
|
|
21
|
+
validate?(ctx: Context, receiver: string): boolean | Promise<boolean>;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export default class VerificationPlugin extends Plugin {
|
|
25
|
+
providers: Registry<typeof Provider> = new Registry();
|
|
26
|
+
interceptors: Registry<Interceptor> = new Registry();
|
|
27
|
+
|
|
28
|
+
intercept: HandlerType = async (context, next) => {
|
|
29
|
+
const { resourceName, actionName, values } = context.action.params;
|
|
30
|
+
const key = `${resourceName}:${actionName}`;
|
|
31
|
+
const interceptor = this.interceptors.get(key);
|
|
32
|
+
|
|
33
|
+
if (!interceptor) {
|
|
34
|
+
return context.throw(400);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const receiver = interceptor.getReceiver(context);
|
|
38
|
+
const content = interceptor.getCode ? interceptor.getCode(context) : values.code;
|
|
39
|
+
if (!receiver || !content) {
|
|
40
|
+
return context.throw(400);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// check if code match, then call next
|
|
44
|
+
// find the code based on action params
|
|
45
|
+
const VerificationRepo = this.db.getRepository('verifications');
|
|
46
|
+
const item = await VerificationRepo.findOne({
|
|
47
|
+
filter: {
|
|
48
|
+
receiver,
|
|
49
|
+
type: key,
|
|
50
|
+
content,
|
|
51
|
+
expiresAt: {
|
|
52
|
+
[Op.gt]: new Date()
|
|
53
|
+
},
|
|
54
|
+
status: CODE_STATUS_UNUSED
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
if (!item) {
|
|
59
|
+
return context.throw(400, { code: 'InvalidSMSCode', message: 'verify by sms code failed' });
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// TODO: code should be removed if exists in values
|
|
63
|
+
// context.action.mergeParams({
|
|
64
|
+
// values: {
|
|
65
|
+
|
|
66
|
+
// }
|
|
67
|
+
// });
|
|
68
|
+
|
|
69
|
+
await next();
|
|
70
|
+
|
|
71
|
+
// or delete
|
|
72
|
+
await item.update({
|
|
73
|
+
status: CODE_STATUS_USED
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
getName(): string {
|
|
79
|
+
return this.getPackageName(__dirname);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async install() {
|
|
83
|
+
const {
|
|
84
|
+
DEFAULT_SMS_VERIFY_CODE_PROVIDER,
|
|
85
|
+
INIT_ALI_SMS_ACCESS_KEY,
|
|
86
|
+
INIT_ALI_SMS_ACCESS_KEY_SECRET,
|
|
87
|
+
INIT_ALI_SMS_ENDPOINT = 'dysmsapi.aliyuncs.com',
|
|
88
|
+
INIT_ALI_SMS_VERIFY_CODE_TEMPLATE,
|
|
89
|
+
INIT_ALI_SMS_VERIFY_CODE_SIGN
|
|
90
|
+
} = process.env;
|
|
91
|
+
|
|
92
|
+
if (INIT_ALI_SMS_ACCESS_KEY
|
|
93
|
+
&& INIT_ALI_SMS_ACCESS_KEY_SECRET
|
|
94
|
+
&& INIT_ALI_SMS_VERIFY_CODE_TEMPLATE
|
|
95
|
+
&& INIT_ALI_SMS_VERIFY_CODE_SIGN
|
|
96
|
+
) {
|
|
97
|
+
const ProviderRepo = this.db.getRepository('verifications_providers');
|
|
98
|
+
await ProviderRepo.create({
|
|
99
|
+
values: {
|
|
100
|
+
id: DEFAULT_SMS_VERIFY_CODE_PROVIDER,
|
|
101
|
+
type: PROVIDER_TYPE_SMS_ALIYUN,
|
|
102
|
+
title: 'Default SMS sender',
|
|
103
|
+
options: {
|
|
104
|
+
accessKeyId: INIT_ALI_SMS_ACCESS_KEY,
|
|
105
|
+
accessKeySecret: INIT_ALI_SMS_ACCESS_KEY_SECRET,
|
|
106
|
+
endpoint: INIT_ALI_SMS_ENDPOINT,
|
|
107
|
+
sign: INIT_ALI_SMS_VERIFY_CODE_SIGN,
|
|
108
|
+
template: INIT_ALI_SMS_VERIFY_CODE_TEMPLATE
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async load() {
|
|
116
|
+
const { app, db, options } = this;
|
|
117
|
+
|
|
118
|
+
app.i18n.addResources('zh-CN', namespace, zhCN);
|
|
119
|
+
|
|
120
|
+
await db.import({
|
|
121
|
+
directory: path.resolve(__dirname, 'collections'),
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
initProviders(this);
|
|
125
|
+
initActions(this);
|
|
126
|
+
|
|
127
|
+
// add middleware to action
|
|
128
|
+
app.resourcer.use(async (context, next) => {
|
|
129
|
+
const { resourceName, actionName, values } = context.action.params;
|
|
130
|
+
const key = `${resourceName}:${actionName}`;
|
|
131
|
+
const interceptor = this.interceptors.get(key);
|
|
132
|
+
if (!interceptor || interceptor.manual) {
|
|
133
|
+
return next();
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return this.intercept(context, next);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
app.acl.allow('verifications', 'create');
|
|
140
|
+
}
|
|
141
|
+
}
|