@ruiapp/rapid-core 0.3.4 → 0.3.6

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.
@@ -0,0 +1,4 @@
1
+ import { IRpdServer } from "../core/server";
2
+ import { Logger } from "../facilities/log/LogFacility";
3
+ export declare function validateLicense(server: IRpdServer): void;
4
+ export declare function tryValidateLicense(logger: Logger, server: IRpdServer): boolean;
package/dist/index.d.ts CHANGED
@@ -9,6 +9,8 @@ export * from "./utilities/accessControlUtility";
9
9
  export * from "./utilities/entityUtility";
10
10
  export * from "./utilities/jwtUtility";
11
11
  export * from "./utilities/timeUtility";
12
+ export * from "./utilities/passwordUtility";
13
+ export * from "./helpers/licenseHelper";
12
14
  export { mapDbRowToEntity } from "./dataAccess/entityMapper";
13
15
  export * as bootstrapApplicationConfig from "./bootstrapApplicationConfig";
14
16
  export { default as MetaManagePlugin } from "./plugins/metaManage/MetaManagePlugin";
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ var qs = require('qs');
9
9
  var dayjs = require('dayjs');
10
10
  var jsonwebtoken = require('jsonwebtoken');
11
11
  var crypto = require('crypto');
12
- var bcrypt = require('bcrypt');
12
+ var bcrypt = require('bcryptjs');
13
13
  var path = require('path');
14
14
  var fs = require('fs');
15
15
  var uuid = require('uuid');
@@ -4361,6 +4361,54 @@ async function generateJwtSecretKey() {
4361
4361
  return encode(exportedKey);
4362
4362
  }
4363
4363
 
4364
+ /**
4365
+ * Generates password hash.
4366
+ * @param password
4367
+ * @param salt
4368
+ * @returns
4369
+ */
4370
+ async function generatePasswordHash(password, salt) {
4371
+ if (!salt) {
4372
+ salt = 10;
4373
+ }
4374
+ const passwordHash = await bcrypt__default["default"].hash(password, salt);
4375
+ return passwordHash;
4376
+ }
4377
+ /**
4378
+ * Validates the password against the hash.
4379
+ * @param password
4380
+ * @param passwordHash
4381
+ * @returns
4382
+ */
4383
+ async function validatePassword(password, passwordHash) {
4384
+ const isMatch = await bcrypt__default["default"].compare(password, passwordHash);
4385
+ return isMatch;
4386
+ }
4387
+
4388
+ function validateLicense(server) {
4389
+ const licenseService = server.getService("licenseService");
4390
+ const license = licenseService.getLicense();
4391
+ if (!license) {
4392
+ const errorMessage = `无法获取系统授权信息。`;
4393
+ throw new Error(errorMessage);
4394
+ }
4395
+ if (licenseService.isExpired()) {
4396
+ const expireDate = lodash.get(license.authority, "expireDate");
4397
+ const errorMessage = `您的系统授权已于${expireDate}过期。`;
4398
+ throw new Error(errorMessage);
4399
+ }
4400
+ }
4401
+ function tryValidateLicense(logger, server) {
4402
+ try {
4403
+ validateLicense(server);
4404
+ return true;
4405
+ }
4406
+ catch (err) {
4407
+ logger.error("授权验证失败:%s", err.message || "");
4408
+ }
4409
+ return false;
4410
+ }
4411
+
4364
4412
  const code$u = "listMetaModels";
4365
4413
  async function handler$u(plugin, ctx, options) {
4366
4414
  const { applicationConfig } = ctx;
@@ -6023,12 +6071,11 @@ async function handler$e(plugin, ctx, options) {
6023
6071
  if (!user) {
6024
6072
  throw new Error("User not found.");
6025
6073
  }
6026
- const isMatch = await bcrypt__default["default"].compare(oldPassword, user.password);
6074
+ const isMatch = await validatePassword(oldPassword, user.password);
6027
6075
  if (!isMatch) {
6028
6076
  throw new Error("旧密码错误。");
6029
6077
  }
6030
- const saltRounds = 10;
6031
- const passwordHash = await bcrypt__default["default"].hash(newPassword, saltRounds);
6078
+ const passwordHash = await generatePasswordHash(newPassword);
6032
6079
  await userDataAccessor.updateById(user.id, {
6033
6080
  password: passwordHash,
6034
6081
  });
@@ -6043,18 +6090,10 @@ var changePassword$1 = /*#__PURE__*/Object.freeze({
6043
6090
 
6044
6091
  const code$d = "createSession";
6045
6092
  async function handler$d(plugin, ctx, options) {
6046
- const { server, input, routerContext } = ctx;
6047
- const { response } = routerContext;
6093
+ const { server, input, routerContext: routeContext, logger } = ctx;
6094
+ const { response } = routeContext;
6048
6095
  const { account, password } = input;
6049
- const licenseService = server.getService("licenseService");
6050
- const license = licenseService.getLicense();
6051
- if (!license) {
6052
- throw new Error(`登录失败,无法获取系统授权信息。`);
6053
- }
6054
- if (licenseService.isExpired()) {
6055
- const expireDate = lodash.get(license.authority, "expireDate");
6056
- throw new Error(`登录失败,系统授权已于${expireDate}过期。`);
6057
- }
6096
+ validateLicense(server);
6058
6097
  const userDataAccessor = server.getDataAccessor({
6059
6098
  singularCode: "oc_user",
6060
6099
  });
@@ -6070,7 +6109,10 @@ async function handler$d(plugin, ctx, options) {
6070
6109
  if (!user) {
6071
6110
  throw new Error("用户名或密码错误。");
6072
6111
  }
6073
- const isMatch = await bcrypt__default["default"].compare(password, user.password);
6112
+ if (user.state !== "enabled") {
6113
+ throw new Error("用户已被禁用,不允许登录。");
6114
+ }
6115
+ const isMatch = await validatePassword(password, user.password);
6074
6116
  if (!isMatch) {
6075
6117
  throw new Error("用户名或密码错误。");
6076
6118
  }
@@ -6170,8 +6212,7 @@ async function handler$a(plugin, ctx, options) {
6170
6212
  if (!user) {
6171
6213
  throw new Error("User not found.");
6172
6214
  }
6173
- const saltRounds = 10;
6174
- const passwordHash = await bcrypt__default["default"].hash(password, saltRounds);
6215
+ const passwordHash = await generatePasswordHash(password);
6175
6216
  await userDataAccessor.updateById(user.id, {
6176
6217
  password: passwordHash,
6177
6218
  });
@@ -7869,6 +7910,7 @@ class CronJobPlugin {
7869
7910
  async executeJob(server, job) {
7870
7911
  const logger = server.getLogger();
7871
7912
  try {
7913
+ validateLicense(server);
7872
7914
  let handlerContext = {
7873
7915
  logger,
7874
7916
  routerContext: null,
@@ -8299,9 +8341,13 @@ exports.bootstrapApplicationConfig = bootstrapApplicationConfig$1;
8299
8341
  exports.createJwt = createJwt;
8300
8342
  exports.decodeJwt = decodeJwt;
8301
8343
  exports.generateJwtSecretKey = generateJwtSecretKey;
8344
+ exports.generatePasswordHash = generatePasswordHash;
8302
8345
  exports.getEntityRelationTargetId = getEntityRelationTargetId;
8303
8346
  exports.getNowString = getNowString;
8304
8347
  exports.getNowStringWithTimezone = getNowStringWithTimezone;
8305
8348
  exports.isAccessAllowed = isAccessAllowed;
8306
8349
  exports.mapDbRowToEntity = mapDbRowToEntity;
8350
+ exports.tryValidateLicense = tryValidateLicense;
8351
+ exports.validateLicense = validateLicense;
8352
+ exports.validatePassword = validatePassword;
8307
8353
  exports.verifyJwt = verifyJwt;
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Generates password hash.
3
+ * @param password
4
+ * @param salt
5
+ * @returns
6
+ */
7
+ export declare function generatePasswordHash(password: string, salt?: number | string): Promise<string>;
8
+ /**
9
+ * Validates the password against the hash.
10
+ * @param password
11
+ * @param passwordHash
12
+ * @returns
13
+ */
14
+ export declare function validatePassword(password: string, passwordHash: string): Promise<boolean>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ruiapp/rapid-core",
3
- "version": "0.3.4",
3
+ "version": "0.3.6",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -19,7 +19,7 @@
19
19
  "typescript": "^4.8.4"
20
20
  },
21
21
  "dependencies": {
22
- "bcrypt": "^5.1.1",
22
+ "bcryptjs": "^3.0.2",
23
23
  "cron": "^3.1.7",
24
24
  "dayjs": "^1.11.7",
25
25
  "jsonwebtoken": "^9.0.2",
@@ -0,0 +1,29 @@
1
+ import { get } from "lodash";
2
+ import { IRpdServer } from "~/core/server";
3
+ import { Logger } from "~/facilities/log/LogFacility";
4
+ import LicenseService from "~/plugins/license/LicenseService";
5
+
6
+ export function validateLicense(server: IRpdServer) {
7
+ const licenseService = server.getService<LicenseService>("licenseService");
8
+ const license = licenseService.getLicense();
9
+ if (!license) {
10
+ const errorMessage = `无法获取系统授权信息。`;
11
+ throw new Error(errorMessage);
12
+ }
13
+ if (licenseService.isExpired()) {
14
+ const expireDate = get(license.authority, "expireDate");
15
+ const errorMessage = `您的系统授权已于${expireDate}过期。`;
16
+ throw new Error(errorMessage);
17
+ }
18
+ }
19
+
20
+ export function tryValidateLicense(logger: Logger, server: IRpdServer) {
21
+ try {
22
+ validateLicense(server);
23
+ return true;
24
+ } catch (err: any) {
25
+ logger.error("授权验证失败:%s", err.message || "");
26
+ }
27
+
28
+ return false;
29
+ }
package/src/index.ts CHANGED
@@ -14,6 +14,9 @@ export * from "./utilities/accessControlUtility";
14
14
  export * from "./utilities/entityUtility";
15
15
  export * from "./utilities/jwtUtility";
16
16
  export * from "./utilities/timeUtility";
17
+ export * from "./utilities/passwordUtility";
18
+
19
+ export * from "./helpers/licenseHelper";
17
20
 
18
21
  export { mapDbRowToEntity } from "./dataAccess/entityMapper";
19
22
 
@@ -1,6 +1,6 @@
1
- import bcrypt from "bcrypt";
2
1
  import { ActionHandlerContext } from "~/core/actionHandler";
3
2
  import { RapidPlugin } from "~/core/server";
3
+ import { generatePasswordHash, validatePassword } from "~/utilities/passwordUtility";
4
4
 
5
5
  export const code = "changePassword";
6
6
 
@@ -38,13 +38,12 @@ export async function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, op
38
38
  throw new Error("User not found.");
39
39
  }
40
40
 
41
- const isMatch = await bcrypt.compare(oldPassword, user.password);
41
+ const isMatch = await validatePassword(oldPassword, user.password);
42
42
  if (!isMatch) {
43
43
  throw new Error("旧密码错误。");
44
44
  }
45
45
 
46
- const saltRounds = 10;
47
- const passwordHash = await bcrypt.hash(newPassword, saltRounds);
46
+ const passwordHash = await generatePasswordHash(newPassword);
48
47
 
49
48
  await userDataAccessor.updateById(user.id, {
50
49
  password: passwordHash,
@@ -1,10 +1,9 @@
1
- import bcrypt from "bcrypt";
2
1
  import { setCookie } from "~/deno-std/http/cookie";
3
2
  import { createJwt } from "~/utilities/jwtUtility";
4
3
  import { ActionHandlerContext } from "~/core/actionHandler";
5
4
  import { RapidPlugin } from "~/core/server";
6
- import LicenseService from "~/plugins/license/LicenseService";
7
- import { get } from "lodash";
5
+ import { validateLicense } from "~/helpers/licenseHelper";
6
+ import { validatePassword } from "~/utilities/passwordUtility";
8
7
 
9
8
  export interface UserAccessToken {
10
9
  sub: "userAccessToken";
@@ -14,19 +13,11 @@ export interface UserAccessToken {
14
13
  export const code = "createSession";
15
14
 
16
15
  export async function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, options: any) {
17
- const { server, input, routerContext } = ctx;
18
- const { response } = routerContext;
16
+ const { server, input, routerContext: routeContext, logger } = ctx;
17
+ const { response } = routeContext;
19
18
  const { account, password } = input;
20
19
 
21
- const licenseService = server.getService<LicenseService>("licenseService");
22
- const license = licenseService.getLicense();
23
- if (!license) {
24
- throw new Error(`登录失败,无法获取系统授权信息。`);
25
- }
26
- if (licenseService.isExpired()) {
27
- const expireDate = get(license.authority, "expireDate");
28
- throw new Error(`登录失败,系统授权已于${expireDate}过期。`);
29
- }
20
+ validateLicense(server);
30
21
 
31
22
  const userDataAccessor = server.getDataAccessor({
32
23
  singularCode: "oc_user",
@@ -46,7 +37,11 @@ export async function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, op
46
37
  throw new Error("用户名或密码错误。");
47
38
  }
48
39
 
49
- const isMatch = await bcrypt.compare(password, user.password);
40
+ if (user.state !== "enabled") {
41
+ throw new Error("用户已被禁用,不允许登录。");
42
+ }
43
+
44
+ const isMatch = await validatePassword(password, user.password);
50
45
  if (!isMatch) {
51
46
  throw new Error("用户名或密码错误。");
52
47
  }
@@ -1,6 +1,6 @@
1
- import bcrypt from "bcrypt";
2
1
  import { ActionHandlerContext } from "~/core/actionHandler";
3
2
  import { RapidPlugin } from "~/core/server";
3
+ import { generatePasswordHash } from "~/utilities/passwordUtility";
4
4
 
5
5
  export const code = "resetPassword";
6
6
 
@@ -27,8 +27,7 @@ export async function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, op
27
27
  throw new Error("User not found.");
28
28
  }
29
29
 
30
- const saltRounds = 10;
31
- const passwordHash = await bcrypt.hash(password, saltRounds);
30
+ const passwordHash = await generatePasswordHash(password);
32
31
 
33
32
  await userDataAccessor.updateById(user.id, {
34
33
  password: passwordHash,
@@ -12,6 +12,7 @@ import {
12
12
  } from "~/core/server";
13
13
  import { ActionHandlerContext } from "~/core/actionHandler";
14
14
  import { find } from "lodash";
15
+ import { validateLicense } from "~/helpers/licenseHelper";
15
16
 
16
17
  class CronJobPlugin implements RapidPlugin {
17
18
  #jobs: CronJobConfiguration[];
@@ -89,6 +90,8 @@ class CronJobPlugin implements RapidPlugin {
89
90
  async executeJob(server: IRpdServer, job: CronJobConfiguration) {
90
91
  const logger = server.getLogger();
91
92
  try {
93
+ validateLicense(server);
94
+
92
95
  let handlerContext: ActionHandlerContext = {
93
96
  logger,
94
97
  routerContext: null,
@@ -0,0 +1,26 @@
1
+ import bcrypt from "bcryptjs";
2
+
3
+ /**
4
+ * Generates password hash.
5
+ * @param password
6
+ * @param salt
7
+ * @returns
8
+ */
9
+ export async function generatePasswordHash(password: string, salt?: number | string): Promise<string> {
10
+ if (!salt) {
11
+ salt = 10;
12
+ }
13
+ const passwordHash = await bcrypt.hash(password, salt);
14
+ return passwordHash;
15
+ }
16
+
17
+ /**
18
+ * Validates the password against the hash.
19
+ * @param password
20
+ * @param passwordHash
21
+ * @returns
22
+ */
23
+ export async function validatePassword(password: string, passwordHash: string): Promise<boolean> {
24
+ const isMatch = await bcrypt.compare(password, passwordHash);
25
+ return isMatch;
26
+ }