@ruiapp/rapid-core 0.3.5 → 0.3.7

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/dist/index.d.ts CHANGED
@@ -9,6 +9,7 @@ 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";
12
13
  export * from "./helpers/licenseHelper";
13
14
  export { mapDbRowToEntity } from "./dataAccess/entityMapper";
14
15
  export * as bootstrapApplicationConfig from "./bootstrapApplicationConfig";
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,30 @@ 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
+
4364
4388
  function validateLicense(server) {
4365
4389
  const licenseService = server.getService("licenseService");
4366
4390
  const license = licenseService.getLicense();
@@ -4385,32 +4409,32 @@ function tryValidateLicense(logger, server) {
4385
4409
  return false;
4386
4410
  }
4387
4411
 
4388
- const code$u = "listMetaModels";
4389
- async function handler$u(plugin, ctx, options) {
4412
+ const code$v = "listMetaModels";
4413
+ async function handler$v(plugin, ctx, options) {
4390
4414
  const { applicationConfig } = ctx;
4391
4415
  ctx.output = { list: applicationConfig.models };
4392
4416
  }
4393
4417
 
4394
4418
  var listMetaModels = /*#__PURE__*/Object.freeze({
4395
4419
  __proto__: null,
4396
- code: code$u,
4397
- handler: handler$u
4420
+ code: code$v,
4421
+ handler: handler$v
4398
4422
  });
4399
4423
 
4400
- const code$t = "listMetaRoutes";
4401
- async function handler$t(plugin, ctx, options) {
4424
+ const code$u = "listMetaRoutes";
4425
+ async function handler$u(plugin, ctx, options) {
4402
4426
  const { applicationConfig } = ctx;
4403
4427
  ctx.output = { list: applicationConfig.routes };
4404
4428
  }
4405
4429
 
4406
4430
  var listMetaRoutes = /*#__PURE__*/Object.freeze({
4407
4431
  __proto__: null,
4408
- code: code$t,
4409
- handler: handler$t
4432
+ code: code$u,
4433
+ handler: handler$u
4410
4434
  });
4411
4435
 
4412
- const code$s = "getMetaModelDetail";
4413
- async function handler$s(plugin, ctx, options) {
4436
+ const code$t = "getMetaModelDetail";
4437
+ async function handler$t(plugin, ctx, options) {
4414
4438
  const { server, input } = ctx;
4415
4439
  const model = server.getModel(input);
4416
4440
  ctx.output = model;
@@ -4418,8 +4442,8 @@ async function handler$s(plugin, ctx, options) {
4418
4442
 
4419
4443
  var getMetaModelDetail = /*#__PURE__*/Object.freeze({
4420
4444
  __proto__: null,
4421
- code: code$s,
4422
- handler: handler$s
4445
+ code: code$t,
4446
+ handler: handler$t
4423
4447
  });
4424
4448
 
4425
4449
  function removeFiltersWithNullValue(filters) {
@@ -4933,9 +4957,9 @@ async function runCollectionEntityActionHandler(ctx, options, code, handleEntity
4933
4957
  }
4934
4958
  }
4935
4959
 
4936
- const code$r = "findCollectionEntities";
4937
- async function handler$r(plugin, ctx, options) {
4938
- await runCollectionEntityActionHandler(ctx, options, code$r, async (entityManager, input) => {
4960
+ const code$s = "findCollectionEntities";
4961
+ async function handler$s(plugin, ctx, options) {
4962
+ await runCollectionEntityActionHandler(ctx, options, code$s, async (entityManager, input) => {
4939
4963
  input.filters = removeFiltersWithNullValue(input.filters);
4940
4964
  input.routeContext = ctx.routerContext;
4941
4965
  const entities = await entityManager.findEntities(input);
@@ -4951,14 +4975,14 @@ async function handler$r(plugin, ctx, options) {
4951
4975
 
4952
4976
  var findCollectionEntities = /*#__PURE__*/Object.freeze({
4953
4977
  __proto__: null,
4954
- code: code$r,
4955
- handler: handler$r
4978
+ code: code$s,
4979
+ handler: handler$s
4956
4980
  });
4957
4981
 
4958
- const code$q = "findCollectionEntityById";
4959
- async function handler$q(plugin, ctx, options) {
4982
+ const code$r = "findCollectionEntityById";
4983
+ async function handler$r(plugin, ctx, options) {
4960
4984
  const { logger, server, input } = ctx;
4961
- logger.debug(`Running ${code$q} handler...`, { input });
4985
+ logger.debug(`Running ${code$r} handler...`, { input });
4962
4986
  const { id } = input;
4963
4987
  const entityManager = server.getEntityManager(options.singularCode);
4964
4988
  const entity = await entityManager.findById({
@@ -4973,13 +4997,13 @@ async function handler$q(plugin, ctx, options) {
4973
4997
 
4974
4998
  var findCollectionEntityById = /*#__PURE__*/Object.freeze({
4975
4999
  __proto__: null,
4976
- code: code$q,
4977
- handler: handler$q
5000
+ code: code$r,
5001
+ handler: handler$r
4978
5002
  });
4979
5003
 
4980
- const code$p = "countCollectionEntities";
4981
- async function handler$p(plugin, ctx, options) {
4982
- await runCollectionEntityActionHandler(ctx, options, code$p, async (entityManager, input) => {
5004
+ const code$q = "countCollectionEntities";
5005
+ async function handler$q(plugin, ctx, options) {
5006
+ await runCollectionEntityActionHandler(ctx, options, code$q, async (entityManager, input) => {
4983
5007
  input.filters = removeFiltersWithNullValue(input.filters);
4984
5008
  input.routeContext = ctx.routerContext;
4985
5009
  const count = await entityManager.count(input);
@@ -4989,16 +5013,16 @@ async function handler$p(plugin, ctx, options) {
4989
5013
 
4990
5014
  var countCollectionEntities = /*#__PURE__*/Object.freeze({
4991
5015
  __proto__: null,
4992
- code: code$p,
4993
- handler: handler$p
5016
+ code: code$q,
5017
+ handler: handler$q
4994
5018
  });
4995
5019
 
4996
- const code$o = "createCollectionEntity";
4997
- async function handler$o(plugin, ctx, options) {
5020
+ const code$p = "createCollectionEntity";
5021
+ async function handler$p(plugin, ctx, options) {
4998
5022
  const { logger, server, input } = ctx;
4999
5023
  const { defaultInput, fixedInput } = options;
5000
5024
  const mergedInput = mergeInput(defaultInput, input, fixedInput);
5001
- logger.debug(`Running ${code$o} handler...`, { defaultInput, fixedInput, mergedInput });
5025
+ logger.debug(`Running ${code$p} handler...`, { defaultInput, fixedInput, mergedInput });
5002
5026
  const entityManager = server.getEntityManager(options.singularCode);
5003
5027
  const output = await entityManager.createEntity({
5004
5028
  entity: input,
@@ -5009,15 +5033,15 @@ async function handler$o(plugin, ctx, options) {
5009
5033
 
5010
5034
  var createCollectionEntity = /*#__PURE__*/Object.freeze({
5011
5035
  __proto__: null,
5012
- code: code$o,
5013
- handler: handler$o
5036
+ code: code$p,
5037
+ handler: handler$p
5014
5038
  });
5015
5039
 
5016
- const code$n = "createCollectionEntitiesBatch";
5017
- async function handler$n(plugin, ctx, options) {
5040
+ const code$o = "createCollectionEntitiesBatch";
5041
+ async function handler$o(plugin, ctx, options) {
5018
5042
  const { logger, server, input } = ctx;
5019
5043
  const { defaultInput, fixedInput } = options;
5020
- logger.debug(`Running ${code$n} handler...`, { defaultInput, fixedInput, input });
5044
+ logger.debug(`Running ${code$o} handler...`, { defaultInput, fixedInput, input });
5021
5045
  const { entities } = input;
5022
5046
  if (!lodash.isArray(entities)) {
5023
5047
  throw new Error("input.entities should be an array.");
@@ -5041,16 +5065,16 @@ async function handler$n(plugin, ctx, options) {
5041
5065
 
5042
5066
  var createCollectionEntitiesBatch = /*#__PURE__*/Object.freeze({
5043
5067
  __proto__: null,
5044
- code: code$n,
5045
- handler: handler$n
5068
+ code: code$o,
5069
+ handler: handler$o
5046
5070
  });
5047
5071
 
5048
- const code$m = "updateCollectionEntityById";
5049
- async function handler$m(plugin, ctx, options) {
5072
+ const code$n = "updateCollectionEntityById";
5073
+ async function handler$n(plugin, ctx, options) {
5050
5074
  const { logger, server, input } = ctx;
5051
5075
  const { defaultInput, fixedInput } = options;
5052
5076
  const mergedInput = mergeInput(defaultInput, input, fixedInput);
5053
- logger.debug(`Running ${code$m} handler...`, { defaultInput, fixedInput, mergedInput });
5077
+ logger.debug(`Running ${code$n} handler...`, { defaultInput, fixedInput, mergedInput });
5054
5078
  const operation = mergedInput.$operation;
5055
5079
  if (operation) {
5056
5080
  delete mergedInput.$operation;
@@ -5078,15 +5102,15 @@ async function handler$m(plugin, ctx, options) {
5078
5102
 
5079
5103
  var updateCollectionEntityById = /*#__PURE__*/Object.freeze({
5080
5104
  __proto__: null,
5081
- code: code$m,
5082
- handler: handler$m
5105
+ code: code$n,
5106
+ handler: handler$n
5083
5107
  });
5084
5108
 
5085
- const code$l = "deleteCollectionEntities";
5086
- async function handler$l(plugin, ctx, options) {
5109
+ const code$m = "deleteCollectionEntities";
5110
+ async function handler$m(plugin, ctx, options) {
5087
5111
  const { logger, server, routerContext } = ctx;
5088
5112
  const input = ctx.input;
5089
- logger.debug(`Running ${code$l} handler...`);
5113
+ logger.debug(`Running ${code$m} handler...`);
5090
5114
  if (!input.filters || !input.filters.length) {
5091
5115
  throw new Error("Filters are required when deleting entities.");
5092
5116
  }
@@ -5107,14 +5131,14 @@ async function handler$l(plugin, ctx, options) {
5107
5131
 
5108
5132
  var deleteCollectionEntities = /*#__PURE__*/Object.freeze({
5109
5133
  __proto__: null,
5110
- code: code$l,
5111
- handler: handler$l
5134
+ code: code$m,
5135
+ handler: handler$m
5112
5136
  });
5113
5137
 
5114
- const code$k = "deleteCollectionEntityById";
5115
- async function handler$k(plugin, ctx, options) {
5138
+ const code$l = "deleteCollectionEntityById";
5139
+ async function handler$l(plugin, ctx, options) {
5116
5140
  const { logger, server, input } = ctx;
5117
- logger.debug(`Running ${code$k} handler...`);
5141
+ logger.debug(`Running ${code$l} handler...`);
5118
5142
  const entityManager = server.getEntityManager(options.singularCode);
5119
5143
  await entityManager.deleteById({
5120
5144
  id: input.id,
@@ -5126,16 +5150,16 @@ async function handler$k(plugin, ctx, options) {
5126
5150
 
5127
5151
  var deleteCollectionEntityById = /*#__PURE__*/Object.freeze({
5128
5152
  __proto__: null,
5129
- code: code$k,
5130
- handler: handler$k
5153
+ code: code$l,
5154
+ handler: handler$l
5131
5155
  });
5132
5156
 
5133
- const code$j = "addEntityRelations";
5134
- async function handler$j(plugin, ctx, options) {
5157
+ const code$k = "addEntityRelations";
5158
+ async function handler$k(plugin, ctx, options) {
5135
5159
  const { logger, server, input } = ctx;
5136
5160
  const { defaultInput, fixedInput } = options;
5137
5161
  const mergedInput = mergeInput(defaultInput, input, fixedInput);
5138
- logger.debug(`Running ${code$j} handler...`, { defaultInput, fixedInput, mergedInput });
5162
+ logger.debug(`Running ${code$k} handler...`, { defaultInput, fixedInput, mergedInput });
5139
5163
  const entityManager = server.getEntityManager(options.singularCode);
5140
5164
  mergedInput.routeContext = ctx.routerContext;
5141
5165
  await entityManager.addRelations(mergedInput, plugin);
@@ -5144,16 +5168,16 @@ async function handler$j(plugin, ctx, options) {
5144
5168
 
5145
5169
  var addEntityRelations = /*#__PURE__*/Object.freeze({
5146
5170
  __proto__: null,
5147
- code: code$j,
5148
- handler: handler$j
5171
+ code: code$k,
5172
+ handler: handler$k
5149
5173
  });
5150
5174
 
5151
- const code$i = "removeEntityRelations";
5152
- async function handler$i(plugin, ctx, options) {
5175
+ const code$j = "removeEntityRelations";
5176
+ async function handler$j(plugin, ctx, options) {
5153
5177
  const { logger, server, input } = ctx;
5154
5178
  const { defaultInput, fixedInput } = options;
5155
5179
  const mergedInput = mergeInput(defaultInput, input, fixedInput);
5156
- logger.debug(`Running ${code$i} handler...`, { defaultInput, fixedInput, mergedInput });
5180
+ logger.debug(`Running ${code$j} handler...`, { defaultInput, fixedInput, mergedInput });
5157
5181
  mergedInput.routeContext = ctx.routerContext;
5158
5182
  const entityManager = server.getEntityManager(options.singularCode);
5159
5183
  await entityManager.removeRelations(mergedInput, plugin);
@@ -5162,16 +5186,16 @@ async function handler$i(plugin, ctx, options) {
5162
5186
 
5163
5187
  var removeEntityRelations = /*#__PURE__*/Object.freeze({
5164
5188
  __proto__: null,
5165
- code: code$i,
5166
- handler: handler$i
5189
+ code: code$j,
5190
+ handler: handler$j
5167
5191
  });
5168
5192
 
5169
- const code$h = "queryDatabase";
5170
- async function handler$h(plugin, ctx, options) {
5193
+ const code$i = "queryDatabase";
5194
+ async function handler$i(plugin, ctx, options) {
5171
5195
  const { logger, server, input } = ctx;
5172
5196
  const { sql, querySingle, defaultInput, fixedInput } = options;
5173
5197
  const mergedInput = mergeInput(defaultInput, input, fixedInput);
5174
- logger.debug(`Running ${code$h} handler...`, { defaultInput, fixedInput, mergedInput });
5198
+ logger.debug(`Running ${code$i} handler...`, { defaultInput, fixedInput, mergedInput });
5175
5199
  const result = await server.queryDatabaseObject(sql, mergedInput);
5176
5200
  if (querySingle) {
5177
5201
  ctx.output = lodash.first(result);
@@ -5183,8 +5207,8 @@ async function handler$h(plugin, ctx, options) {
5183
5207
 
5184
5208
  var queryDatabase = /*#__PURE__*/Object.freeze({
5185
5209
  __proto__: null,
5186
- code: code$h,
5187
- handler: handler$h
5210
+ code: code$i,
5211
+ handler: handler$i
5188
5212
  });
5189
5213
 
5190
5214
  /**
@@ -5362,17 +5386,17 @@ async function sendSourceResponse(proxyCtx, targetRes) {
5362
5386
  srcRes.body = targetRes.body;
5363
5387
  }
5364
5388
 
5365
- const code$g = "httpProxy";
5366
- async function handler$g(plugin, ctx, options) {
5389
+ const code$h = "httpProxy";
5390
+ async function handler$h(plugin, ctx, options) {
5367
5391
  const { logger } = ctx;
5368
- logger.debug(`Running ${code$g} handler...`);
5392
+ logger.debug(`Running ${code$h} handler...`);
5369
5393
  await doProxy(ctx.routerContext, options);
5370
5394
  }
5371
5395
 
5372
5396
  var httpProxy = /*#__PURE__*/Object.freeze({
5373
5397
  __proto__: null,
5374
- code: code$g,
5375
- handler: handler$g
5398
+ code: code$h,
5399
+ handler: handler$h
5376
5400
  });
5377
5401
 
5378
5402
  /**
@@ -5419,8 +5443,8 @@ class RouteManager {
5419
5443
  }
5420
5444
  }
5421
5445
 
5422
- const code$f = "generateSn";
5423
- async function handler$f(plugin, ctx, options) {
5446
+ const code$g = "generateSn";
5447
+ async function handler$g(plugin, ctx, options) {
5424
5448
  const { server, routerContext } = ctx;
5425
5449
  const input = ctx.input;
5426
5450
  if (options?.ruleCode) {
@@ -5438,8 +5462,8 @@ async function handler$f(plugin, ctx, options) {
5438
5462
 
5439
5463
  var generateSn$1 = /*#__PURE__*/Object.freeze({
5440
5464
  __proto__: null,
5441
- code: code$f,
5442
- handler: handler$f
5465
+ code: code$g,
5466
+ handler: handler$g
5443
5467
  });
5444
5468
 
5445
5469
  var pluginActionHandlers$8 = [generateSn$1];
@@ -6018,8 +6042,8 @@ class WebhooksPlugin {
6018
6042
  }
6019
6043
  }
6020
6044
 
6021
- const code$e = "changePassword";
6022
- async function handler$e(plugin, ctx, options) {
6045
+ const code$f = "changePassword";
6046
+ async function handler$f(plugin, ctx, options) {
6023
6047
  const { server, input, routerContext } = ctx;
6024
6048
  const { id, oldPassword, newPassword } = input;
6025
6049
  const userId = routerContext.state.userId;
@@ -6047,12 +6071,11 @@ async function handler$e(plugin, ctx, options) {
6047
6071
  if (!user) {
6048
6072
  throw new Error("User not found.");
6049
6073
  }
6050
- const isMatch = await bcrypt__default["default"].compare(oldPassword, user.password);
6074
+ const isMatch = await validatePassword(oldPassword, user.password);
6051
6075
  if (!isMatch) {
6052
6076
  throw new Error("旧密码错误。");
6053
6077
  }
6054
- const saltRounds = 10;
6055
- const passwordHash = await bcrypt__default["default"].hash(newPassword, saltRounds);
6078
+ const passwordHash = await generatePasswordHash(newPassword);
6056
6079
  await userDataAccessor.updateById(user.id, {
6057
6080
  password: passwordHash,
6058
6081
  });
@@ -6061,12 +6084,12 @@ async function handler$e(plugin, ctx, options) {
6061
6084
 
6062
6085
  var changePassword$1 = /*#__PURE__*/Object.freeze({
6063
6086
  __proto__: null,
6064
- code: code$e,
6065
- handler: handler$e
6087
+ code: code$f,
6088
+ handler: handler$f
6066
6089
  });
6067
6090
 
6068
- const code$d = "createSession";
6069
- async function handler$d(plugin, ctx, options) {
6091
+ const code$e = "createSession";
6092
+ async function handler$e(plugin, ctx, options) {
6070
6093
  const { server, input, routerContext: routeContext, logger } = ctx;
6071
6094
  const { response } = routeContext;
6072
6095
  const { account, password } = input;
@@ -6086,7 +6109,10 @@ async function handler$d(plugin, ctx, options) {
6086
6109
  if (!user) {
6087
6110
  throw new Error("用户名或密码错误。");
6088
6111
  }
6089
- 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);
6090
6116
  if (!isMatch) {
6091
6117
  throw new Error("用户名或密码错误。");
6092
6118
  }
@@ -6110,12 +6136,12 @@ async function handler$d(plugin, ctx, options) {
6110
6136
 
6111
6137
  var createSession = /*#__PURE__*/Object.freeze({
6112
6138
  __proto__: null,
6113
- code: code$d,
6114
- handler: handler$d
6139
+ code: code$e,
6140
+ handler: handler$e
6115
6141
  });
6116
6142
 
6117
- const code$c = "deleteSession";
6118
- async function handler$c(plugin, ctx, options) {
6143
+ const code$d = "deleteSession";
6144
+ async function handler$d(plugin, ctx, options) {
6119
6145
  const { server, input, routerContext } = ctx;
6120
6146
  const { response } = routerContext;
6121
6147
  setCookie(response.headers, {
@@ -6128,12 +6154,12 @@ async function handler$c(plugin, ctx, options) {
6128
6154
 
6129
6155
  var deleteSession = /*#__PURE__*/Object.freeze({
6130
6156
  __proto__: null,
6131
- code: code$c,
6132
- handler: handler$c
6157
+ code: code$d,
6158
+ handler: handler$d
6133
6159
  });
6134
6160
 
6135
- const code$b = "getMyProfile";
6136
- async function handler$b(plugin, ctx, options) {
6161
+ const code$c = "getMyProfile";
6162
+ async function handler$c(plugin, ctx, options) {
6137
6163
  const { server, input, routerContext } = ctx;
6138
6164
  const userId = routerContext.state.userId;
6139
6165
  if (!userId) {
@@ -6163,12 +6189,12 @@ async function handler$b(plugin, ctx, options) {
6163
6189
 
6164
6190
  var getMyProfile$2 = /*#__PURE__*/Object.freeze({
6165
6191
  __proto__: null,
6166
- code: code$b,
6167
- handler: handler$b
6192
+ code: code$c,
6193
+ handler: handler$c
6168
6194
  });
6169
6195
 
6170
- const code$a = "resetPassword";
6171
- async function handler$a(plugin, ctx, options) {
6196
+ const code$b = "resetPassword";
6197
+ async function handler$b(plugin, ctx, options) {
6172
6198
  const { server, input, routerContext } = ctx;
6173
6199
  const { userId, password } = input;
6174
6200
  const userDataAccessor = server.getDataAccessor({
@@ -6186,8 +6212,7 @@ async function handler$a(plugin, ctx, options) {
6186
6212
  if (!user) {
6187
6213
  throw new Error("User not found.");
6188
6214
  }
6189
- const saltRounds = 10;
6190
- const passwordHash = await bcrypt__default["default"].hash(password, saltRounds);
6215
+ const passwordHash = await generatePasswordHash(password);
6191
6216
  await userDataAccessor.updateById(user.id, {
6192
6217
  password: passwordHash,
6193
6218
  });
@@ -6196,8 +6221,8 @@ async function handler$a(plugin, ctx, options) {
6196
6221
 
6197
6222
  var resetPassword$1 = /*#__PURE__*/Object.freeze({
6198
6223
  __proto__: null,
6199
- code: code$a,
6200
- handler: handler$a
6224
+ code: code$b,
6225
+ handler: handler$b
6201
6226
  });
6202
6227
 
6203
6228
  var pluginActionHandlers$7 = [changePassword$1, createSession, deleteSession, getMyProfile$2, resetPassword$1];
@@ -6420,8 +6445,8 @@ function getFileBaseName(pathname) {
6420
6445
  return path__default["default"].basename(pathname, extName);
6421
6446
  }
6422
6447
 
6423
- const code$9 = "downloadDocument";
6424
- async function handler$9(plugin, ctx, options) {
6448
+ const code$a = "downloadDocument";
6449
+ async function handler$a(plugin, ctx, options) {
6425
6450
  const { server, applicationConfig, routerContext, input } = ctx;
6426
6451
  const { request, response } = routerContext;
6427
6452
  const documentDataAccessor = ctx.server.getDataAccessor({
@@ -6477,12 +6502,12 @@ async function handler$9(plugin, ctx, options) {
6477
6502
 
6478
6503
  var downloadDocumentActionHandler = /*#__PURE__*/Object.freeze({
6479
6504
  __proto__: null,
6480
- code: code$9,
6481
- handler: handler$9
6505
+ code: code$a,
6506
+ handler: handler$a
6482
6507
  });
6483
6508
 
6484
- const code$8 = "downloadFile";
6485
- async function handler$8(plugin, ctx, options) {
6509
+ const code$9 = "downloadFile";
6510
+ async function handler$9(plugin, ctx, options) {
6486
6511
  const { server, applicationConfig, routerContext } = ctx;
6487
6512
  const { request, response } = routerContext;
6488
6513
  //TODO: only public files can download by this handler
@@ -6508,12 +6533,12 @@ async function handler$8(plugin, ctx, options) {
6508
6533
 
6509
6534
  var downloadFileActionHandler = /*#__PURE__*/Object.freeze({
6510
6535
  __proto__: null,
6511
- code: code$8,
6512
- handler: handler$8
6536
+ code: code$9,
6537
+ handler: handler$9
6513
6538
  });
6514
6539
 
6515
- const code$7 = "uploadFile";
6516
- async function handler$7(plugin, ctx, options) {
6540
+ const code$8 = "uploadFile";
6541
+ async function handler$8(plugin, ctx, options) {
6517
6542
  const { server, applicationConfig, routerContext, input } = ctx;
6518
6543
  let file = input.file || input.files;
6519
6544
  if (lodash.isArray(file)) {
@@ -6534,8 +6559,8 @@ async function handler$7(plugin, ctx, options) {
6534
6559
 
6535
6560
  var uploadFileActionHandler = /*#__PURE__*/Object.freeze({
6536
6561
  __proto__: null,
6537
- code: code$7,
6538
- handler: handler$7
6562
+ code: code$8,
6563
+ handler: handler$8
6539
6564
  });
6540
6565
 
6541
6566
  var getMyProfile = {
@@ -6611,8 +6636,8 @@ class FileManager {
6611
6636
  }
6612
6637
  }
6613
6638
 
6614
- const code$6 = "getLicense";
6615
- async function handler$6(plugin, ctx, options) {
6639
+ const code$7 = "getLicense";
6640
+ async function handler$7(plugin, ctx, options) {
6616
6641
  const { server, routerContext } = ctx;
6617
6642
  const licenseService = server.getService("licenseService");
6618
6643
  const license = licenseService.getLicense();
@@ -6620,12 +6645,27 @@ async function handler$6(plugin, ctx, options) {
6620
6645
  }
6621
6646
 
6622
6647
  var getLicense$1 = /*#__PURE__*/Object.freeze({
6648
+ __proto__: null,
6649
+ code: code$7,
6650
+ handler: handler$7
6651
+ });
6652
+
6653
+ const code$6 = "updateLicense";
6654
+ async function handler$6(plugin, ctx, options) {
6655
+ const { server, routerContext } = ctx;
6656
+ const input = ctx.input;
6657
+ const licenseService = server.getService("licenseService");
6658
+ const license = await licenseService.updateLicense(input.certText);
6659
+ ctx.output = license;
6660
+ }
6661
+
6662
+ var updateLicense$1 = /*#__PURE__*/Object.freeze({
6623
6663
  __proto__: null,
6624
6664
  code: code$6,
6625
6665
  handler: handler$6
6626
6666
  });
6627
6667
 
6628
- var pluginActionHandlers$6 = [getLicense$1];
6668
+ var pluginActionHandlers$6 = [getLicense$1, updateLicense$1];
6629
6669
 
6630
6670
  var pluginModels$4 = [];
6631
6671
 
@@ -6643,7 +6683,21 @@ var getLicense = {
6643
6683
  ],
6644
6684
  };
6645
6685
 
6646
- var pluginRoutes$5 = [getLicense];
6686
+ var updateLicense = {
6687
+ namespace: "svc",
6688
+ name: "svc.updateLicense",
6689
+ code: "svc.updateLicense",
6690
+ type: "RESTful",
6691
+ method: "POST",
6692
+ endpoint: "/svc/license",
6693
+ actions: [
6694
+ {
6695
+ code: "updateLicense",
6696
+ },
6697
+ ],
6698
+ };
6699
+
6700
+ var pluginRoutes$5 = [getLicense, updateLicense];
6647
6701
 
6648
6702
  function getEncryptionIV(input) {
6649
6703
  const hash = crypto__default["default"].createHash("sha512").update(input).digest("hex");
@@ -6699,12 +6753,9 @@ class LicenseService {
6699
6753
  async loadLicense() {
6700
6754
  const settingService = this.#server.getService("settingService");
6701
6755
  const licenseSettings = await settingService.getSystemSettingValues("license");
6702
- const { deployId } = licenseSettings;
6703
- const certText = licenseSettings.cert;
6704
- const certJSON = Buffer.from(certText, "base64").toString();
6705
- const cert = JSON.parse(certJSON);
6756
+ const { deployId, cert: certText } = licenseSettings;
6706
6757
  try {
6707
- const license = extractCertLicense(this.#encryptionKey, deployId, cert);
6758
+ const license = this.parseLicense(deployId, certText);
6708
6759
  this.#license = license;
6709
6760
  }
6710
6761
  catch (error) {
@@ -6715,6 +6766,26 @@ class LicenseService {
6715
6766
  getLicense() {
6716
6767
  return this.#license;
6717
6768
  }
6769
+ parseLicense(deployId, certText) {
6770
+ const certJSON = Buffer.from(certText, "base64").toString();
6771
+ const cert = JSON.parse(certJSON);
6772
+ return extractCertLicense(this.#encryptionKey, deployId, cert);
6773
+ }
6774
+ async updateLicense(certText) {
6775
+ const settingService = this.#server.getService("settingService");
6776
+ const deployId = await settingService.getSystemSettingValue("license", "deployId");
6777
+ let license;
6778
+ try {
6779
+ license = this.parseLicense(deployId, certText);
6780
+ }
6781
+ catch (error) {
6782
+ this.#server.getLogger().error("Parse license failed.", error);
6783
+ throw new Error("Parse license failed.");
6784
+ }
6785
+ await settingService.setSystemSettingValue("license", "cert", certText);
6786
+ this.#license = license;
6787
+ return license;
6788
+ }
6718
6789
  isExpired() {
6719
6790
  if (!this.#license) {
6720
6791
  return true;
@@ -8316,6 +8387,7 @@ exports.bootstrapApplicationConfig = bootstrapApplicationConfig$1;
8316
8387
  exports.createJwt = createJwt;
8317
8388
  exports.decodeJwt = decodeJwt;
8318
8389
  exports.generateJwtSecretKey = generateJwtSecretKey;
8390
+ exports.generatePasswordHash = generatePasswordHash;
8319
8391
  exports.getEntityRelationTargetId = getEntityRelationTargetId;
8320
8392
  exports.getNowString = getNowString;
8321
8393
  exports.getNowStringWithTimezone = getNowStringWithTimezone;
@@ -8323,4 +8395,5 @@ exports.isAccessAllowed = isAccessAllowed;
8323
8395
  exports.mapDbRowToEntity = mapDbRowToEntity;
8324
8396
  exports.tryValidateLicense = tryValidateLicense;
8325
8397
  exports.validateLicense = validateLicense;
8398
+ exports.validatePassword = validatePassword;
8326
8399
  exports.verifyJwt = verifyJwt;
@@ -15,6 +15,8 @@ export default class LicenseService {
15
15
  constructor(server: IRpdServer, encryptionKey: string);
16
16
  loadLicense(): Promise<void>;
17
17
  getLicense(): RpdLicense;
18
+ parseLicense(deployId: string, certText: string): RpdLicense;
19
+ updateLicense(certText: string): Promise<RpdLicense>;
18
20
  isExpired(): boolean;
19
21
  getQuota(name: string): any;
20
22
  isOutOfQuota(name: string, currentAmount: number): boolean;
@@ -1,3 +1,4 @@
1
1
  import * as getLicense from "./getLicense";
2
- declare const _default: (typeof getLicense)[];
2
+ import * as updateLicense from "./updateLicense";
3
+ declare const _default: (typeof getLicense | typeof updateLicense)[];
3
4
  export default _default;
@@ -0,0 +1,9 @@
1
+ import { ActionHandlerContext } from "../../../core/actionHandler";
2
+ import { RapidPlugin } from "../../../core/server";
3
+ export interface UpdateLicenseOptions {
4
+ }
5
+ export interface UpdateLicenseInput {
6
+ certText: string;
7
+ }
8
+ export declare const code = "updateLicense";
9
+ export declare function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, options: UpdateLicenseOptions): Promise<void>;
@@ -1,4 +1,4 @@
1
- declare const _default: {
1
+ declare const _default: ({
2
2
  namespace: string;
3
3
  name: string;
4
4
  code: string;
@@ -8,5 +8,15 @@ declare const _default: {
8
8
  actions: {
9
9
  code: string;
10
10
  }[];
11
- }[];
11
+ } | {
12
+ namespace: string;
13
+ name: string;
14
+ code: string;
15
+ type: "RESTful";
16
+ method: "POST";
17
+ endpoint: string;
18
+ actions: {
19
+ code: string;
20
+ }[];
21
+ })[];
12
22
  export default _default;
@@ -0,0 +1,12 @@
1
+ declare const _default: {
2
+ namespace: string;
3
+ name: string;
4
+ code: string;
5
+ type: "RESTful";
6
+ method: "POST";
7
+ endpoint: string;
8
+ actions: {
9
+ code: string;
10
+ }[];
11
+ };
12
+ export default _default;
@@ -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.5",
3
+ "version": "0.3.7",
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",
package/src/index.ts CHANGED
@@ -14,6 +14,7 @@ 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";
17
18
 
18
19
  export * from "./helpers/licenseHelper";
19
20
 
@@ -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,9 +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
5
  import { validateLicense } from "~/helpers/licenseHelper";
6
+ import { validatePassword } from "~/utilities/passwordUtility";
7
7
 
8
8
  export interface UserAccessToken {
9
9
  sub: "userAccessToken";
@@ -37,7 +37,11 @@ export async function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, op
37
37
  throw new Error("用户名或密码错误。");
38
38
  }
39
39
 
40
- 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);
41
45
  if (!isMatch) {
42
46
  throw new Error("用户名或密码错误。");
43
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,
@@ -37,13 +37,10 @@ export default class LicenseService {
37
37
  async loadLicense(): Promise<void> {
38
38
  const settingService = this.#server.getService<SettingService>("settingService");
39
39
  const licenseSettings = await settingService.getSystemSettingValues("license");
40
- const { deployId } = licenseSettings as LicenseSettings;
41
- const certText = licenseSettings.cert;
42
- const certJSON = Buffer.from(certText, "base64").toString();
43
- const cert: RpdCert = JSON.parse(certJSON);
40
+ const { deployId, cert: certText } = licenseSettings as LicenseSettings;
44
41
 
45
42
  try {
46
- const license = extractCertLicense(this.#encryptionKey, deployId, cert);
43
+ const license = this.parseLicense(deployId, certText);
47
44
  this.#license = license;
48
45
  } catch (error) {
49
46
  this.#server.getLogger().error("Loading license failed.", error);
@@ -55,6 +52,29 @@ export default class LicenseService {
55
52
  return this.#license;
56
53
  }
57
54
 
55
+ parseLicense(deployId: string, certText: string): RpdLicense {
56
+ const certJSON = Buffer.from(certText, "base64").toString();
57
+ const cert: RpdCert = JSON.parse(certJSON);
58
+ return extractCertLicense(this.#encryptionKey, deployId, cert);
59
+ }
60
+
61
+ async updateLicense(certText: string) {
62
+ const settingService = this.#server.getService<SettingService>("settingService");
63
+ const deployId: string = await settingService.getSystemSettingValue("license", "deployId");
64
+
65
+ let license: RpdLicense;
66
+ try {
67
+ license = this.parseLicense(deployId, certText);
68
+ } catch (error) {
69
+ this.#server.getLogger().error("Parse license failed.", error);
70
+ throw new Error("Parse license failed.");
71
+ }
72
+
73
+ await settingService.setSystemSettingValue("license", "cert", certText);
74
+ this.#license = license;
75
+ return license;
76
+ }
77
+
58
78
  isExpired() {
59
79
  if (!this.#license) {
60
80
  return true;
@@ -1,4 +1,5 @@
1
1
  import { IPluginActionHandler } from "~/core/actionHandler";
2
2
  import * as getLicense from "./getLicense";
3
+ import * as updateLicense from "./updateLicense";
3
4
 
4
- export default [getLicense] satisfies IPluginActionHandler[];
5
+ export default [getLicense, updateLicense] satisfies IPluginActionHandler[];
@@ -0,0 +1,24 @@
1
+ import { ActionHandlerContext } from "~/core/actionHandler";
2
+ import { RapidPlugin } from "~/core/server";
3
+ import LicenseService from "../LicenseService";
4
+
5
+ export interface UpdateLicenseOptions {}
6
+
7
+ export interface UpdateLicenseInput {
8
+ certText: string;
9
+ }
10
+
11
+ export const code = "updateLicense";
12
+
13
+ export async function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, options: UpdateLicenseOptions) {
14
+ const { server, routerContext } = ctx;
15
+ const { response } = routerContext;
16
+
17
+ const input: UpdateLicenseInput = ctx.input;
18
+
19
+ const licenseService = server.getService<LicenseService>("licenseService");
20
+
21
+ const license = await licenseService.updateLicense(input.certText);
22
+
23
+ ctx.output = license;
24
+ }
@@ -1,3 +1,4 @@
1
1
  import getLicense from "./getLicense";
2
+ import updateLicense from "./updateLicense";
2
3
 
3
- export default [getLicense];
4
+ export default [getLicense, updateLicense];
@@ -0,0 +1,15 @@
1
+ import { RpdRoute } from "~/types";
2
+
3
+ export default {
4
+ namespace: "svc",
5
+ name: "svc.updateLicense",
6
+ code: "svc.updateLicense",
7
+ type: "RESTful",
8
+ method: "POST",
9
+ endpoint: "/svc/license",
10
+ actions: [
11
+ {
12
+ code: "updateLicense",
13
+ },
14
+ ],
15
+ } satisfies RpdRoute;
@@ -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
+ }