@nocobase/plugin-verification 1.7.0-beta.8 → 1.7.0-beta.9

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.
Files changed (71) hide show
  1. package/dist/client/{providerTypes/index.d.ts → VerificationMenu.d.ts} +5 -4
  2. package/dist/client/cfedbdcfbe65d5f6.js +10 -0
  3. package/dist/client/d0b398212e5aa575.js +10 -0
  4. package/dist/client/index.d.ts +7 -0
  5. package/dist/client/index.js +1 -1
  6. package/dist/client/locale/index.d.ts +1 -1
  7. package/dist/client/otp-verification/VerificationCode.d.ts +16 -0
  8. package/dist/client/otp-verification/sms/AdminSettingsForm.d.ts +12 -0
  9. package/dist/client/otp-verification/sms/BindForm.d.ts +11 -0
  10. package/dist/client/otp-verification/sms/VerificationForm.d.ts +11 -0
  11. package/dist/client/otp-verification/sms/index.d.ts +26 -0
  12. package/dist/client/otp-verification/sms/provider-manager.d.ts +19 -0
  13. package/dist/client/{VerificationProviders.d.ts → otp-verification/sms/providers/AliyunSettings.d.ts} +1 -1
  14. package/dist/{server/actions/index.d.ts → client/otp-verification/sms/providers/TencentSettings.d.ts} +2 -3
  15. package/dist/client/schemas/verificators.d.ts +66 -0
  16. package/dist/client/verification-manager/index.d.ts +32 -0
  17. package/dist/client/{ProviderOptions.d.ts → verificators/VerificatorSelect.d.ts} +1 -2
  18. package/dist/client/verificators/Verificators.d.ts +12 -0
  19. package/dist/client/verificators/verification-types.d.ts +24 -0
  20. package/dist/collections/verificators.d.ts +50 -0
  21. package/dist/collections/verificators.js +70 -0
  22. package/dist/constants.d.ts +11 -0
  23. package/dist/constants.js +42 -0
  24. package/dist/externalVersion.js +13 -13
  25. package/dist/locale/en-US.json +17 -1
  26. package/dist/locale/zh-CN.json +19 -2
  27. package/dist/node_modules/@alicloud/dysmsapi20170525/package.json +1 -1
  28. package/dist/node_modules/@alicloud/openapi-client/package.json +1 -1
  29. package/dist/node_modules/@alicloud/tea-util/package.json +1 -1
  30. package/dist/node_modules/tencentcloud-sdk-nodejs/package.json +1 -1
  31. package/dist/server/Plugin.d.ts +5 -16
  32. package/dist/server/Plugin.js +57 -72
  33. package/dist/server/actions/verificators.d.ts +18 -0
  34. package/dist/server/actions/verificators.js +175 -0
  35. package/dist/server/{actions/verifications.d.ts → collections/otp-records.d.ts} +2 -2
  36. package/dist/server/collections/otp-records.js +75 -0
  37. package/dist/server/collections/users-verificators.d.ts +14 -0
  38. package/dist/server/collections/users-verificators.js +58 -0
  39. package/dist/server/collections/verificators.d.ts +10 -0
  40. package/dist/server/{actions/index.js → collections/verificators.js} +10 -19
  41. package/dist/server/constants.d.ts +0 -2
  42. package/dist/server/constants.js +2 -8
  43. package/dist/server/index.d.ts +5 -2
  44. package/dist/server/index.js +12 -5
  45. package/dist/server/migrations/20250111192640-providers2verificators.d.ts +14 -0
  46. package/dist/server/migrations/20250111192640-providers2verificators.js +83 -0
  47. package/dist/server/otp-verification/index.d.ts +25 -0
  48. package/dist/server/otp-verification/index.js +94 -0
  49. package/dist/server/otp-verification/sms/index.d.ts +37 -0
  50. package/dist/server/otp-verification/sms/index.js +87 -0
  51. package/dist/server/{providers/Provider.d.ts → otp-verification/sms/providers/index.d.ts} +2 -4
  52. package/dist/server/{providers/Provider.js → otp-verification/sms/providers/index.js} +8 -10
  53. package/dist/server/{providers → otp-verification/sms/providers}/sms-aliyun.d.ts +3 -3
  54. package/dist/server/{providers → otp-verification/sms/providers}/sms-aliyun.js +4 -4
  55. package/dist/server/{providers → otp-verification/sms/providers}/sms-tencent.d.ts +3 -3
  56. package/dist/server/{providers → otp-verification/sms/providers}/sms-tencent.js +4 -4
  57. package/dist/server/otp-verification/sms/resource/sms-otp-providers.d.ts +16 -0
  58. package/dist/server/otp-verification/sms/resource/sms-otp-providers.js +41 -0
  59. package/dist/server/otp-verification/sms/resource/sms-otp.d.ts +18 -0
  60. package/dist/server/otp-verification/sms/resource/sms-otp.js +141 -0
  61. package/dist/server/verification-manager.d.ts +68 -0
  62. package/dist/server/verification-manager.js +223 -0
  63. package/dist/server/verification.d.ts +70 -0
  64. package/dist/server/verification.js +70 -0
  65. package/package.json +8 -6
  66. package/dist/client/7551e1f2e04bca2f.js +0 -10
  67. package/dist/client/providerTypes/sms-aliyun.d.ts +0 -66
  68. package/dist/client/providerTypes/sms-tencent.d.ts +0 -66
  69. package/dist/server/actions/verifications.js +0 -146
  70. package/dist/server/providers/index.d.ts +0 -15
  71. package/dist/server/providers/index.js +0 -52
@@ -0,0 +1,41 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __getOwnPropNames = Object.getOwnPropertyNames;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __export = (target, all) => {
15
+ for (var name in all)
16
+ __defProp(target, name, { get: all[name], enumerable: true });
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
+ var sms_otp_providers_exports = {};
28
+ __export(sms_otp_providers_exports, {
29
+ default: () => sms_otp_providers_default
30
+ });
31
+ module.exports = __toCommonJS(sms_otp_providers_exports);
32
+ var sms_otp_providers_default = {
33
+ name: "smsOTPProviders",
34
+ actions: {
35
+ list: async (ctx, next) => {
36
+ const plugin = ctx.app.pm.get("verification");
37
+ ctx.body = plugin.smsOTPProviderManager.listProviders();
38
+ await next();
39
+ }
40
+ }
41
+ };
@@ -0,0 +1,18 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+ import { Context, Next } from '@nocobase/actions';
10
+ declare function create(ctx: Context, next: Next): Promise<any>;
11
+ declare const _default: {
12
+ name: string;
13
+ actions: {
14
+ create: typeof create;
15
+ publicCreate: typeof create;
16
+ };
17
+ };
18
+ export default _default;
@@ -0,0 +1,141 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __create = Object.create;
11
+ var __defProp = Object.defineProperty;
12
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
13
+ var __getOwnPropNames = Object.getOwnPropertyNames;
14
+ var __getProtoOf = Object.getPrototypeOf;
15
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
16
+ var __export = (target, all) => {
17
+ for (var name in all)
18
+ __defProp(target, name, { get: all[name], enumerable: true });
19
+ };
20
+ var __copyProps = (to, from, except, desc) => {
21
+ if (from && typeof from === "object" || typeof from === "function") {
22
+ for (let key of __getOwnPropNames(from))
23
+ if (!__hasOwnProp.call(to, key) && key !== except)
24
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
25
+ }
26
+ return to;
27
+ };
28
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
29
+ // If the importer is in node compatibility mode or this is not an ESM
30
+ // file that has been converted to a CommonJS file using a Babel-
31
+ // compatible transform (i.e. "__esModule" has not been set), then set
32
+ // "default" to the CommonJS "module.exports" for node compatibility.
33
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
34
+ mod
35
+ ));
36
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
37
+ var sms_otp_exports = {};
38
+ __export(sms_otp_exports, {
39
+ default: () => sms_otp_default
40
+ });
41
+ module.exports = __toCommonJS(sms_otp_exports);
42
+ var import_dayjs = __toESM(require("dayjs"));
43
+ var import_crypto = require("crypto");
44
+ var import_util = require("util");
45
+ var import_constants = require("../../../constants");
46
+ var import__2 = require("../../..");
47
+ const asyncRandomInt = (0, import_util.promisify)(import_crypto.randomInt);
48
+ async function create(ctx, next) {
49
+ var _a;
50
+ const { action: actionName, verificator: verificatorName } = ((_a = ctx.action.params) == null ? void 0 : _a.values) || {};
51
+ const plugin = ctx.app.getPlugin("verification");
52
+ const verificationManager = plugin.verificationManager;
53
+ const action = verificationManager.actions.get(actionName);
54
+ if (!action) {
55
+ return ctx.throw(400, "Invalid action type");
56
+ }
57
+ if (!verificatorName) {
58
+ return ctx.throw(400, "Invalid verificator");
59
+ }
60
+ const verificator = await ctx.db.getRepository("verificators").findOne({
61
+ filter: {
62
+ name: verificatorName
63
+ }
64
+ });
65
+ if (!verificator) {
66
+ return ctx.throw(400, "Invalid verificator");
67
+ }
68
+ const Verification = verificationManager.getVerification(verificator.verificationType);
69
+ const verification = new Verification({
70
+ ctx,
71
+ verificator,
72
+ options: verificator.options
73
+ });
74
+ const provider = await verification.getProvider();
75
+ if (!provider) {
76
+ ctx.log.error(`[verification] no provider for action (${actionName}) provided`);
77
+ return ctx.throw(500, "Invalid provider");
78
+ }
79
+ const { boundInfo } = await verificationManager.getAndValidateBoundInfo(ctx, action, verification);
80
+ const { uuid: receiver } = boundInfo;
81
+ const record = await ctx.db.getRepository("otpRecords").findOne({
82
+ filter: {
83
+ action: actionName,
84
+ receiver,
85
+ status: import_constants.CODE_STATUS_UNUSED,
86
+ expiresAt: {
87
+ $dateAfter: /* @__PURE__ */ new Date()
88
+ }
89
+ }
90
+ });
91
+ if (record) {
92
+ const seconds = (0, import_dayjs.default)(record.get("expiresAt")).diff((0, import_dayjs.default)(), "seconds");
93
+ return ctx.throw(429, {
94
+ code: "RateLimit",
95
+ message: ctx.t("Please don't retry in {{time}} seconds", { time: seconds, ns: import__2.namespace })
96
+ });
97
+ }
98
+ const code = (await asyncRandomInt(999999)).toString(10).padStart(6, "0");
99
+ try {
100
+ await provider.send(receiver, { code });
101
+ } catch (error) {
102
+ switch (error.name) {
103
+ case "InvalidReceiver":
104
+ return ctx.throw(400, {
105
+ code: "InvalidReceiver",
106
+ message: ctx.t("Not a valid cellphone number, please re-enter", { ns: import__2.namespace })
107
+ });
108
+ case "RateLimit":
109
+ return ctx.throw(429, ctx.t("You are trying so frequently, please slow down", { ns: import__2.namespace }));
110
+ default:
111
+ ctx.log.error(error);
112
+ return ctx.throw(
113
+ 500,
114
+ ctx.t("Verification send failed, please try later or contact to administrator", { ns: import__2.namespace })
115
+ );
116
+ }
117
+ }
118
+ const result = await ctx.db.getRepository("otpRecords").create({
119
+ values: {
120
+ id: (0, import_crypto.randomUUID)(),
121
+ action: actionName,
122
+ receiver,
123
+ code,
124
+ expiresAt: Date.now() + (verification.expiresIn ?? 60) * 1e3,
125
+ status: import_constants.CODE_STATUS_UNUSED,
126
+ verificatorName
127
+ }
128
+ });
129
+ ctx.body = {
130
+ id: result.id,
131
+ expiresAt: result.expiresAt
132
+ };
133
+ return next();
134
+ }
135
+ var sms_otp_default = {
136
+ name: "smsOTP",
137
+ actions: {
138
+ create,
139
+ publicCreate: create
140
+ }
141
+ };
@@ -0,0 +1,68 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+ import { Registry } from '@nocobase/utils';
10
+ import { Verification, VerificationExtend } from './verification';
11
+ import { Context, Next } from '@nocobase/actions';
12
+ import { Database } from '@nocobase/database';
13
+ export type VerificationTypeOptions = {
14
+ title: string;
15
+ description?: string;
16
+ bindingRequired?: boolean;
17
+ verification: VerificationExtend<Verification>;
18
+ };
19
+ type SceneRule = (scene: string, verificationType: string) => boolean;
20
+ export interface ActionOptions {
21
+ manual?: boolean;
22
+ getUserIdFromCtx?(ctx: Context): number | Promise<number>;
23
+ getBoundInfoFromCtx?(ctx: Context): any | Promise<any>;
24
+ getVerifyParams?(ctx: Context): any | Promise<any>;
25
+ onVerifySuccess?(ctx: Context, userId: number, verifyResult: any): any | Promise<any>;
26
+ onVerifyFail?(ctx: Context, err: Error, userId: number): any | Promise<any>;
27
+ }
28
+ export interface SceneOptions {
29
+ actions: {
30
+ [key: string]: ActionOptions;
31
+ };
32
+ getVerificators?(ctx: Context): Promise<string[]>;
33
+ }
34
+ export declare class VerificationManager {
35
+ db: Database;
36
+ verificationTypes: Registry<VerificationTypeOptions>;
37
+ scenes: Registry<SceneOptions>;
38
+ sceneRules: SceneRule[];
39
+ actions: Registry<ActionOptions & {
40
+ scene?: string;
41
+ }>;
42
+ constructor({ db }: {
43
+ db: any;
44
+ });
45
+ registerVerificationType(type: string, options: VerificationTypeOptions): void;
46
+ listTypes(): {
47
+ name: string;
48
+ title: string;
49
+ }[];
50
+ addSceneRule(rule: SceneRule): void;
51
+ registerAction(action: string, options: ActionOptions): void;
52
+ registerScene(scene: string, options: SceneOptions): void;
53
+ getVerificationTypesByScene(scene: string): any[];
54
+ getVerification(type: string): VerificationExtend<Verification>;
55
+ getVerificator(verificatorName: string): Promise<any>;
56
+ getVerificators(verificatorNames: string[]): Promise<any>;
57
+ getBoundRecord(userId: number, verificator: string): Promise<any>;
58
+ getAndValidateBoundInfo(ctx: Context, action: ActionOptions, verification: Verification): Promise<{
59
+ boundInfo: {
60
+ uuid: string;
61
+ };
62
+ userId: number;
63
+ }>;
64
+ private validateAndGetVerificator;
65
+ verify(ctx: Context, next: Next): Promise<void>;
66
+ middleware(): (ctx: Context, next: Next) => Promise<any>;
67
+ }
68
+ export {};
@@ -0,0 +1,223 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __getOwnPropNames = Object.getOwnPropertyNames;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __export = (target, all) => {
15
+ for (var name in all)
16
+ __defProp(target, name, { get: all[name], enumerable: true });
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
+ var verification_manager_exports = {};
28
+ __export(verification_manager_exports, {
29
+ VerificationManager: () => VerificationManager
30
+ });
31
+ module.exports = __toCommonJS(verification_manager_exports);
32
+ var import_utils = require("@nocobase/utils");
33
+ class VerificationManager {
34
+ db;
35
+ verificationTypes = new import_utils.Registry();
36
+ scenes = new import_utils.Registry();
37
+ sceneRules = new Array();
38
+ actions = new import_utils.Registry();
39
+ constructor({ db }) {
40
+ this.db = db;
41
+ }
42
+ registerVerificationType(type, options) {
43
+ this.verificationTypes.register(type, options);
44
+ }
45
+ listTypes() {
46
+ return Array.from(this.verificationTypes.getEntities()).map(([verificationType, options]) => ({
47
+ name: verificationType,
48
+ title: options.title
49
+ }));
50
+ }
51
+ addSceneRule(rule) {
52
+ this.sceneRules.push(rule);
53
+ }
54
+ registerAction(action, options) {
55
+ this.actions.register(action, options);
56
+ }
57
+ registerScene(scene, options) {
58
+ this.scenes.register(scene, options);
59
+ const { actions } = options;
60
+ for (const [action, actionOptions] of Object.entries(actions)) {
61
+ this.actions.register(action, {
62
+ ...actionOptions,
63
+ scene
64
+ });
65
+ }
66
+ }
67
+ getVerificationTypesByScene(scene) {
68
+ const verificationTypes = [];
69
+ for (const [type, options] of this.verificationTypes.getEntities()) {
70
+ const item = { type, title: options.title };
71
+ if (this.sceneRules.some((rule) => rule(scene, type))) {
72
+ verificationTypes.push(item);
73
+ }
74
+ }
75
+ return verificationTypes;
76
+ }
77
+ getVerification(type) {
78
+ const verificationType = this.verificationTypes.get(type);
79
+ if (!verificationType) {
80
+ throw new Error(`Invalid verification type: ${type}`);
81
+ }
82
+ return verificationType.verification;
83
+ }
84
+ async getVerificator(verificatorName) {
85
+ return await this.db.getRepository("verificators").findOne({
86
+ filter: {
87
+ name: verificatorName
88
+ }
89
+ });
90
+ }
91
+ async getVerificators(verificatorNames) {
92
+ return await this.db.getRepository("verificators").find({
93
+ filter: {
94
+ name: verificatorNames
95
+ }
96
+ });
97
+ }
98
+ async getBoundRecord(userId, verificator) {
99
+ return await this.db.getRepository("usersVerificators").findOne({
100
+ filter: {
101
+ userId,
102
+ verificator
103
+ }
104
+ });
105
+ }
106
+ async getAndValidateBoundInfo(ctx, action, verification) {
107
+ var _a, _b;
108
+ let userId;
109
+ let boundInfo;
110
+ if (action.getBoundInfoFromCtx) {
111
+ boundInfo = await action.getBoundInfoFromCtx(ctx);
112
+ } else {
113
+ if (action.getUserIdFromCtx) {
114
+ userId = await action.getUserIdFromCtx(ctx);
115
+ } else {
116
+ userId = (_b = (_a = ctx.auth) == null ? void 0 : _a.user) == null ? void 0 : _b.id;
117
+ }
118
+ if (!userId) {
119
+ ctx.throw(400, "Invalid user id");
120
+ }
121
+ boundInfo = await verification.getBoundInfo(userId);
122
+ }
123
+ await verification.validateBoundInfo(boundInfo);
124
+ return { boundInfo, userId };
125
+ }
126
+ async validateAndGetVerificator(ctx, scene, verificatorName) {
127
+ let verificator;
128
+ if (!verificatorName) {
129
+ return null;
130
+ }
131
+ if (scene) {
132
+ const sceneOptions = this.scenes.get(scene);
133
+ if (sceneOptions.getVerificators) {
134
+ const verificators = await sceneOptions.getVerificators(ctx);
135
+ if (!verificators.includes(verificatorName)) {
136
+ return null;
137
+ }
138
+ verificator = await this.getVerificator(verificatorName);
139
+ if (!verificator) {
140
+ return null;
141
+ }
142
+ } else {
143
+ const verificationTypes = this.getVerificationTypesByScene(scene);
144
+ const verificators = await this.db.getRepository("verificators").find({
145
+ filter: {
146
+ verificationType: verificationTypes.map((item) => item.type)
147
+ }
148
+ });
149
+ verificator = verificators.find((item) => item.name === verificatorName);
150
+ if (!verificator) {
151
+ return null;
152
+ }
153
+ }
154
+ } else {
155
+ verificator = await this.getVerificator(verificatorName);
156
+ if (!verificator) {
157
+ return null;
158
+ }
159
+ }
160
+ return verificator;
161
+ }
162
+ // verify manually
163
+ async verify(ctx, next) {
164
+ var _a, _b;
165
+ const { resourceName, actionName } = ctx.action;
166
+ const key = `${resourceName}:${actionName}`;
167
+ const action = this.actions.get(key);
168
+ if (!action) {
169
+ ctx.throw(400, "Invalid action");
170
+ }
171
+ const { verificator: verificatorName } = ctx.action.params.values || {};
172
+ const verificator = await this.validateAndGetVerificator(ctx, action.scene, verificatorName);
173
+ if (!verificator) {
174
+ ctx.throw(400, "Invalid verificator");
175
+ }
176
+ const verifyParams = action.getVerifyParams ? await action.getVerifyParams(ctx) : ctx.action.params.values;
177
+ if (!verifyParams) {
178
+ ctx.throw(400, "Invalid verify params");
179
+ }
180
+ const plugin = ctx.app.pm.get("verification");
181
+ const verificationManager = plugin.verificationManager;
182
+ const Verification2 = verificationManager.getVerification(verificator.verificationType);
183
+ const verification = new Verification2({ ctx, verificator, options: verificator.options });
184
+ const { boundInfo, userId } = await this.getAndValidateBoundInfo(ctx, action, verification);
185
+ try {
186
+ const verifyResult = await verification.verify({
187
+ resource: resourceName,
188
+ action: actionName,
189
+ userId,
190
+ boundInfo,
191
+ verifyParams
192
+ });
193
+ try {
194
+ await ((_a = action.onVerifySuccess) == null ? void 0 : _a.call(action, ctx, userId, verifyResult));
195
+ await next();
196
+ } catch (err) {
197
+ ctx.log.error(err, { module: "verification", method: "verify" });
198
+ throw err;
199
+ } finally {
200
+ await verification.onActionComplete({ userId, verifyResult });
201
+ }
202
+ } catch (err) {
203
+ await ((_b = action.onVerifyFail) == null ? void 0 : _b.call(action, ctx, err, userId));
204
+ throw err;
205
+ }
206
+ }
207
+ middleware() {
208
+ const self = this;
209
+ return async function verificationMiddleware(ctx, next) {
210
+ const { resourceName, actionName } = ctx.action;
211
+ const key = `${resourceName}:${actionName}`;
212
+ const action = self.actions.get(key);
213
+ if (!action || action.manual) {
214
+ return next();
215
+ }
216
+ return self.verify(ctx, next);
217
+ };
218
+ }
219
+ }
220
+ // Annotate the CommonJS export names for ESM import in node:
221
+ 0 && (module.exports = {
222
+ VerificationManager
223
+ });
@@ -0,0 +1,70 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+ import { Context } from '@nocobase/actions';
10
+ import { Model } from '@nocobase/database';
11
+ export interface IVerification {
12
+ verify(options: {
13
+ resource: string;
14
+ action: string;
15
+ userId: number;
16
+ boundInfo: any;
17
+ verifyParams?: any;
18
+ }): Promise<any>;
19
+ onActionComplete?(options: {
20
+ userId: number;
21
+ verifyResult: any;
22
+ }): Promise<any>;
23
+ getBoundInfo?(userId: number): Promise<any>;
24
+ getPublicBoundInfo?(userId: number): Promise<{
25
+ bound: boolean;
26
+ publicInfo?: any;
27
+ }>;
28
+ validateBoundInfo?(boundInfo: string): Promise<boolean>;
29
+ bind?(userId: number, resource?: string, action?: string): Promise<{
30
+ uuid: string;
31
+ meta?: any;
32
+ }>;
33
+ }
34
+ export declare abstract class Verification implements IVerification {
35
+ verificator: Model;
36
+ protected ctx: Context;
37
+ protected options: Record<string, any>;
38
+ constructor({ ctx, verificator, options }: {
39
+ ctx: any;
40
+ verificator: any;
41
+ options: any;
42
+ });
43
+ get throughRepo(): import("@nocobase/database").Repository<any, any>;
44
+ abstract verify({ resource, action, userId, boundInfo, verifyParams }: {
45
+ resource: any;
46
+ action: any;
47
+ userId: any;
48
+ boundInfo: any;
49
+ verifyParams: any;
50
+ }): Promise<any>;
51
+ onActionComplete(options: {
52
+ userId: number;
53
+ verifyResult: any;
54
+ }): Promise<any>;
55
+ bind(userId: number, resource?: string, action?: string): Promise<{
56
+ uuid: string;
57
+ meta?: any;
58
+ }>;
59
+ getBoundInfo(userId: number): Promise<any>;
60
+ getPublicBoundInfo(userId: number): Promise<{
61
+ bound: boolean;
62
+ publicInfo?: any;
63
+ }>;
64
+ validateBoundInfo(boundInfo: any): Promise<boolean>;
65
+ }
66
+ export type VerificationExtend<T extends Verification> = new ({ ctx, verificator, options }: {
67
+ ctx: any;
68
+ verificator: any;
69
+ options: any;
70
+ }) => T;
@@ -0,0 +1,70 @@
1
+ /**
2
+ * This file is part of the NocoBase (R) project.
3
+ * Copyright (c) 2020-2024 NocoBase Co., Ltd.
4
+ * Authors: NocoBase Team.
5
+ *
6
+ * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
+ * For more information, please refer to: https://www.nocobase.com/agreement.
8
+ */
9
+
10
+ var __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __getOwnPropNames = Object.getOwnPropertyNames;
13
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
14
+ var __export = (target, all) => {
15
+ for (var name in all)
16
+ __defProp(target, name, { get: all[name], enumerable: true });
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
+ var verification_exports = {};
28
+ __export(verification_exports, {
29
+ Verification: () => Verification
30
+ });
31
+ module.exports = __toCommonJS(verification_exports);
32
+ class Verification {
33
+ verificator;
34
+ ctx;
35
+ options;
36
+ constructor({ ctx, verificator, options }) {
37
+ this.ctx = ctx;
38
+ this.verificator = verificator;
39
+ this.options = options;
40
+ }
41
+ get throughRepo() {
42
+ return this.ctx.db.getRepository("usersVerificators");
43
+ }
44
+ async onActionComplete(options) {
45
+ }
46
+ async bind(userId, resource, action) {
47
+ throw new Error("Not implemented");
48
+ }
49
+ async getBoundInfo(userId) {
50
+ return this.throughRepo.findOne({
51
+ filter: {
52
+ verificator: this.verificator.name,
53
+ userId
54
+ }
55
+ });
56
+ }
57
+ async getPublicBoundInfo(userId) {
58
+ const boundInfo = await this.getBoundInfo(userId);
59
+ return {
60
+ bound: boundInfo ? true : false
61
+ };
62
+ }
63
+ async validateBoundInfo(boundInfo) {
64
+ return true;
65
+ }
66
+ }
67
+ // Annotate the CommonJS export names for ESM import in node:
68
+ 0 && (module.exports = {
69
+ Verification
70
+ });
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@nocobase/plugin-verification",
3
3
  "displayName": "Verification",
4
- "displayName.zh-CN": "验证码",
5
- "description": "verification setting.",
6
- "description.zh-CN": "验证码配置。",
7
- "version": "1.7.0-beta.8",
4
+ "displayName.zh-CN": "验证",
5
+ "description": "User identity verification management, including SMS, TOTP authenticator, with extensibility.",
6
+ "description.zh-CN": "用户身份验证管理,包含短信、TOTP 认证器等,可扩展。",
7
+ "version": "1.7.0-beta.9",
8
8
  "license": "AGPL-3.0",
9
9
  "main": "./dist/server/index.js",
10
10
  "homepage": "https://docs.nocobase.com/handbook/verification",
@@ -31,8 +31,10 @@
31
31
  "@nocobase/test": "1.x",
32
32
  "@nocobase/utils": "1.x"
33
33
  },
34
- "gitHead": "9ad35ee90db98d95dfa660645d155f4f4e81b47c",
34
+ "gitHead": "7013a5080f3695d7750ab21005c90d2172c16480",
35
35
  "keywords": [
36
- "Authentication"
36
+ "Authentication",
37
+ "Verification",
38
+ "Security"
37
39
  ]
38
40
  }