@ruiapp/rapid-core 0.1.26 → 0.1.28

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 (57) hide show
  1. package/dist/core/pluginManager.d.ts +3 -1
  2. package/dist/core/server.d.ts +4 -1
  3. package/dist/index.d.ts +1 -0
  4. package/dist/index.js +565 -80
  5. package/dist/plugins/auth/actionHandlers/changePassword.d.ts +4 -0
  6. package/dist/plugins/auth/actionHandlers/index.d.ts +2 -1
  7. package/dist/plugins/auth/actionHandlers/resetPassword.d.ts +4 -0
  8. package/dist/plugins/sequence/SequencePlugin.d.ts +18 -0
  9. package/dist/plugins/sequence/SequenceService.d.ts +15 -0
  10. package/dist/plugins/sequence/actionHandlers/generateSn.d.ts +7 -0
  11. package/dist/plugins/sequence/actionHandlers/index.d.ts +3 -0
  12. package/dist/plugins/sequence/models/SequenceAutoIncrementRecord.d.ts +3 -0
  13. package/dist/plugins/sequence/models/SequenceRule.d.ts +3 -0
  14. package/dist/plugins/sequence/models/index.d.ts +2 -0
  15. package/dist/plugins/sequence/routes/generateSn.d.ts +12 -0
  16. package/dist/plugins/sequence/routes/index.d.ts +12 -0
  17. package/dist/plugins/sequence/segment-utility.d.ts +1 -0
  18. package/dist/plugins/sequence/segments/autoIncrement.d.ts +5 -0
  19. package/dist/plugins/sequence/segments/dayOfMonth.d.ts +5 -0
  20. package/dist/plugins/sequence/segments/index.d.ts +8 -0
  21. package/dist/plugins/sequence/segments/literal.d.ts +5 -0
  22. package/dist/plugins/sequence/segments/month.d.ts +5 -0
  23. package/dist/plugins/sequence/segments/parameter.d.ts +5 -0
  24. package/dist/plugins/sequence/segments/year.d.ts +5 -0
  25. package/dist/plugins/sequence/sequence-types.d.ts +8 -0
  26. package/dist/server.d.ts +3 -2
  27. package/dist/types.d.ts +43 -0
  28. package/package.json +3 -1
  29. package/src/core/pluginManager.ts +13 -1
  30. package/src/core/response.ts +1 -0
  31. package/src/core/server.ts +4 -1
  32. package/src/dataAccess/entityManager.ts +3 -0
  33. package/src/index.ts +1 -0
  34. package/src/plugins/auth/actionHandlers/changePassword.ts +58 -0
  35. package/src/plugins/auth/actionHandlers/createSession.ts +7 -1
  36. package/src/plugins/auth/actionHandlers/index.ts +2 -0
  37. package/src/plugins/auth/actionHandlers/resetPassword.ts +42 -0
  38. package/src/plugins/sequence/SequencePlugin.ts +122 -0
  39. package/src/plugins/sequence/SequenceService.ts +72 -0
  40. package/src/plugins/sequence/actionHandlers/generateSn.ts +36 -0
  41. package/src/plugins/sequence/actionHandlers/index.ts +6 -0
  42. package/src/plugins/sequence/models/SequenceAutoIncrementRecord.ts +49 -0
  43. package/src/plugins/sequence/models/SequenceRule.ts +42 -0
  44. package/src/plugins/sequence/models/index.ts +7 -0
  45. package/src/plugins/sequence/routes/generateSn.ts +15 -0
  46. package/src/plugins/sequence/routes/index.ts +5 -0
  47. package/src/plugins/sequence/segment-utility.ts +11 -0
  48. package/src/plugins/sequence/segments/autoIncrement.ts +77 -0
  49. package/src/plugins/sequence/segments/dayOfMonth.ts +16 -0
  50. package/src/plugins/sequence/segments/index.ts +16 -0
  51. package/src/plugins/sequence/segments/literal.ts +9 -0
  52. package/src/plugins/sequence/segments/month.ts +16 -0
  53. package/src/plugins/sequence/segments/parameter.ts +17 -0
  54. package/src/plugins/sequence/segments/year.ts +16 -0
  55. package/src/plugins/sequence/sequence-types.ts +10 -0
  56. package/src/server.ts +17 -3
  57. package/src/types.ts +62 -0
@@ -0,0 +1,4 @@
1
+ import { ActionHandlerContext } from "../../../core/actionHandler";
2
+ import { RapidPlugin } from "../../../core/server";
3
+ export declare const code = "changePassword";
4
+ export declare function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, options: any): Promise<void>;
@@ -1,5 +1,6 @@
1
1
  import * as createSession from "./createSession";
2
2
  import * as deleteSession from "./deleteSession";
3
3
  import * as getMyProfile from "./getMyProfile";
4
- declare const _default: (typeof createSession | typeof deleteSession | typeof getMyProfile)[];
4
+ import * as resetPassword from "./resetPassword";
5
+ declare const _default: (typeof createSession | typeof deleteSession | typeof getMyProfile | typeof resetPassword)[];
5
6
  export default _default;
@@ -0,0 +1,4 @@
1
+ import { ActionHandlerContext } from "../../../core/actionHandler";
2
+ import { RapidPlugin } from "../../../core/server";
3
+ export declare const code = "resetPassword";
4
+ export declare function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, options: any): Promise<void>;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Sequence plugin
3
+ */
4
+ import { CreateEntityOptions, RpdApplicationConfig, RpdDataModel } from "../../types";
5
+ import { IRpdServer, RapidPlugin, RpdConfigurationItemOptions, RpdServerPluginConfigurableTargetOptions, RpdServerPluginExtendingAbilities } from "../../core/server";
6
+ declare class SequencePlugin implements RapidPlugin {
7
+ get code(): string;
8
+ get description(): string;
9
+ get extendingAbilities(): RpdServerPluginExtendingAbilities[];
10
+ get configurableTargets(): RpdServerPluginConfigurableTargetOptions[];
11
+ get configurations(): RpdConfigurationItemOptions[];
12
+ registerActionHandlers(server: IRpdServer): Promise<any>;
13
+ configureModels(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any>;
14
+ configureRoutes(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any>;
15
+ onApplicationLoaded(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<void>;
16
+ beforeCreateEntity(server: IRpdServer, model: RpdDataModel, options: CreateEntityOptions): Promise<void>;
17
+ }
18
+ export default SequencePlugin;
@@ -0,0 +1,15 @@
1
+ import { IRpdServer } from "../../core/server";
2
+ import { SequenceSegmentConfig } from "../../types";
3
+ export interface GenerateSequenceNumbersInput {
4
+ ruleCode: string;
5
+ parameters: Record<string, string>;
6
+ amount: number;
7
+ }
8
+ export interface GenerateSequenceNumbersOutput {
9
+ sequences: string[];
10
+ }
11
+ export interface SegmentResolver {
12
+ segmentType: string;
13
+ resolveSegmentValue(server: IRpdServer, ruleCode: string, config: SequenceSegmentConfig, input: GenerateSequenceNumbersInput): Promise<string>;
14
+ }
15
+ export declare function generateSn(server: IRpdServer, input: GenerateSequenceNumbersInput): Promise<string[]>;
@@ -0,0 +1,7 @@
1
+ import { ActionHandlerContext } from "../../../core/actionHandler";
2
+ import { RapidPlugin } from "../../../core/server";
3
+ export interface GenerateSequenceNumbersOptions {
4
+ ruleCode: string;
5
+ }
6
+ export declare const code = "generateSn";
7
+ export declare function handler(plugin: RapidPlugin, ctx: ActionHandlerContext, options: GenerateSequenceNumbersOptions): Promise<void>;
@@ -0,0 +1,3 @@
1
+ import * as generateSn from "./generateSn";
2
+ declare const _default: (typeof generateSn)[];
3
+ export default _default;
@@ -0,0 +1,3 @@
1
+ import { RpdDataModel } from "../../../types";
2
+ declare const _default: RpdDataModel;
3
+ export default _default;
@@ -0,0 +1,3 @@
1
+ import { RpdDataModel } from "../../../types";
2
+ declare const _default: RpdDataModel;
3
+ export default _default;
@@ -0,0 +1,2 @@
1
+ declare const _default: import("../../..").RpdDataModel[];
2
+ 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,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 @@
1
+ export declare function padSegment(segment: string, length?: number, fillString?: string): string;
@@ -0,0 +1,5 @@
1
+ import { SequenceAutoIncrementSegmentConfig } from "../../../types";
2
+ import { GenerateSequenceNumbersInput } from "../SequenceService";
3
+ import { IRpdServer } from "../../../core/server";
4
+ export declare const segmentType = "autoIncrement";
5
+ export declare function resolveSegmentValue(server: IRpdServer, ruleCode: string, config: SequenceAutoIncrementSegmentConfig, input: GenerateSequenceNumbersInput): Promise<string>;
@@ -0,0 +1,5 @@
1
+ import { SequenceDayOfMonthSegmentConfig } from "../../../types";
2
+ import { GenerateSequenceNumbersInput } from "../SequenceService";
3
+ import { IRpdServer } from "../../../core/server";
4
+ export declare const segmentType = "dayOfMonth";
5
+ export declare function resolveSegmentValue(server: IRpdServer, ruleCode: string, config: SequenceDayOfMonthSegmentConfig, input: GenerateSequenceNumbersInput): Promise<string>;
@@ -0,0 +1,8 @@
1
+ import * as literal from "./literal";
2
+ import * as year from "./year";
3
+ import * as month from "./month";
4
+ import * as dayOfMonth from "./dayOfMonth";
5
+ import * as parameter from "./parameter";
6
+ import * as autoIncrement from "./autoIncrement";
7
+ declare const _default: (typeof literal | typeof year | typeof month | typeof dayOfMonth | typeof parameter | typeof autoIncrement)[];
8
+ export default _default;
@@ -0,0 +1,5 @@
1
+ import { SequenceLiteralSegmentConfig } from "../../../types";
2
+ import { GenerateSequenceNumbersInput } from "../SequenceService";
3
+ import { IRpdServer } from "../../../core/server";
4
+ export declare const segmentType = "literal";
5
+ export declare function resolveSegmentValue(server: IRpdServer, ruleCode: string, config: SequenceLiteralSegmentConfig, input: GenerateSequenceNumbersInput): Promise<string>;
@@ -0,0 +1,5 @@
1
+ import { SequenceMonthSegmentConfig } from "../../../types";
2
+ import { GenerateSequenceNumbersInput } from "../SequenceService";
3
+ import { IRpdServer } from "../../../core/server";
4
+ export declare const segmentType = "month";
5
+ export declare function resolveSegmentValue(server: IRpdServer, ruleCode: string, config: SequenceMonthSegmentConfig, input: GenerateSequenceNumbersInput): Promise<string>;
@@ -0,0 +1,5 @@
1
+ import { SequenceParameterSegmentConfig } from "../../../types";
2
+ import { GenerateSequenceNumbersInput } from "../SequenceService";
3
+ import { IRpdServer } from "../../../core/server";
4
+ export declare const segmentType = "parameter";
5
+ export declare function resolveSegmentValue(server: IRpdServer, ruleCode: string, config: SequenceParameterSegmentConfig, input: GenerateSequenceNumbersInput): Promise<string>;
@@ -0,0 +1,5 @@
1
+ import { SequenceYearSegmentConfig } from "../../../types";
2
+ import { GenerateSequenceNumbersInput } from "../SequenceService";
3
+ import { IRpdServer } from "../../../core/server";
4
+ export declare const segmentType = "year";
5
+ export declare function resolveSegmentValue(server: IRpdServer, ruleCode: string, config: SequenceYearSegmentConfig, input: GenerateSequenceNumbersInput): Promise<string>;
@@ -0,0 +1,8 @@
1
+ import { SequenceSegmentConfig } from "../../types";
2
+ export type PropertySequenceConfig = {
3
+ autoGenerate: boolean;
4
+ ruleConfig: SequenceRuleConfig;
5
+ };
6
+ export type SequenceRuleConfig = {
7
+ segments: SequenceSegmentConfig[];
8
+ };
package/dist/server.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { GetDataAccessorOptions, GetModelOptions, IDatabaseAccessor, IDatabaseConfig, IQueryBuilder, IRpdDataAccessor, RpdApplicationConfig, RpdDataModel, RpdServerEventTypes, RapidServerConfig, RpdDataModelProperty } from "./types";
1
+ import { GetDataAccessorOptions, GetModelOptions, IDatabaseAccessor, IDatabaseConfig, IQueryBuilder, IRpdDataAccessor, RpdApplicationConfig, RpdDataModel, RpdServerEventTypes, RapidServerConfig, RpdDataModelProperty, CreateEntityOptions } from "./types";
2
2
  import { ActionHandler, ActionHandlerContext, IPluginActionHandler } from "./core/actionHandler";
3
3
  import { IRpdServer, RapidPlugin } from "./core/server";
4
4
  import { Next } from "./core/routeContext";
@@ -39,6 +39,7 @@ export declare class RapidServer implements IRpdServer {
39
39
  queryDatabaseObject(sql: string, params?: unknown[] | Record<string, unknown>): Promise<any[]>;
40
40
  tryQueryDatabaseObject(sql: string, params?: unknown[] | Record<string, unknown>): Promise<any[]>;
41
41
  get middlewares(): any[];
42
- handleRequest(request: Request, next: Next): any;
42
+ handleRequest(request: Request, next: Next): Promise<Response>;
43
43
  beforeRunRouteActions(handlerContext: ActionHandlerContext): Promise<void>;
44
+ beforeCreateEntity(model: RpdDataModel, options: CreateEntityOptions): Promise<void>;
44
45
  }
package/dist/types.d.ts CHANGED
@@ -355,3 +355,46 @@ export interface RemoveEntityRelationsOptions {
355
355
  [k: string]: any;
356
356
  }[];
357
357
  }
358
+ export type SequenceSegmentConfig = SequenceLiteralSegmentConfig | SequenceYearSegmentConfig | SequenceMonthSegmentConfig | SequenceDayOfMonthSegmentConfig | SequenceDayOfWeekSegmentConfig | SequenceDayOfYearSegmentConfig | SequenceParameterSegmentConfig | SequenceAutoIncrementSegmentConfig;
359
+ export type SequenceLiteralSegmentConfig = {
360
+ type: "literal";
361
+ content: string;
362
+ };
363
+ export type SequenceYearSegmentConfig = {
364
+ type: "year";
365
+ padding?: string;
366
+ length?: number;
367
+ };
368
+ export type SequenceMonthSegmentConfig = {
369
+ type: "month";
370
+ padding?: string;
371
+ length?: number;
372
+ };
373
+ export type SequenceDayOfMonthSegmentConfig = {
374
+ type: "dayOfMonth";
375
+ padding?: string;
376
+ length?: number;
377
+ };
378
+ export type SequenceDayOfWeekSegmentConfig = {
379
+ type: "dayOfWeek";
380
+ padding?: string;
381
+ length?: number;
382
+ };
383
+ export type SequenceDayOfYearSegmentConfig = {
384
+ type: "dayOfYear";
385
+ padding?: string;
386
+ length?: number;
387
+ };
388
+ export type SequenceParameterSegmentConfig = {
389
+ type: "parameter";
390
+ parameterName: string;
391
+ padding?: string;
392
+ length?: number;
393
+ };
394
+ export type SequenceAutoIncrementSegmentConfig = {
395
+ type: "autoIncrement";
396
+ scope: string;
397
+ period: "forever" | "day" | "month" | "year";
398
+ padding?: string;
399
+ length?: number;
400
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ruiapp/rapid-core",
3
- "version": "0.1.26",
3
+ "version": "0.1.28",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -18,6 +18,8 @@
18
18
  "typescript": "^4.8.4"
19
19
  },
20
20
  "dependencies": {
21
+ "bcrypt": "^5.1.1",
22
+ "dayjs": "^1.11.7",
21
23
  "jsonwebtoken": "^9.0.2",
22
24
  "koa-tree-router": "^0.12.1",
23
25
  "lodash": "^4.17.21",
@@ -1,4 +1,4 @@
1
- import { RpdApplicationConfig } from "~/types";
1
+ import { CreateEntityOptions, RpdApplicationConfig, RpdDataModel } from "~/types";
2
2
  import { IRpdServer, RapidPlugin } from "./server";
3
3
  import { RouteContext } from "./routeContext";
4
4
  import { ActionHandlerContext } from "./actionHandler";
@@ -159,6 +159,18 @@ class PluginManager {
159
159
  }
160
160
  }
161
161
  }
162
+
163
+ /** 在创建实体前调用。 */
164
+ async beforeCreateEntity(
165
+ model: RpdDataModel,
166
+ options: CreateEntityOptions,
167
+ ) {
168
+ for (const plugin of this.#plugins) {
169
+ if (plugin.beforeCreateEntity) {
170
+ await plugin.beforeCreateEntity(this.#server, model, options);
171
+ }
172
+ }
173
+ }
162
174
  }
163
175
 
164
176
  export default PluginManager;
@@ -50,6 +50,7 @@ export class RapidResponse {
50
50
  headers?: HeadersInit,
51
51
  ) {
52
52
  const body = JSON.stringify(obj);
53
+ this.headers.set("Content-Type", "application/json");
53
54
  const responseHeaders = new Headers(this.headers);
54
55
  if (headers) {
55
56
  mergeHeaders(responseHeaders, headers);
@@ -1,4 +1,4 @@
1
- import { GetDataAccessorOptions, GetModelOptions, IDatabaseConfig, IQueryBuilder, IRpdDataAccessor, RapidServerConfig, RpdApplicationConfig, RpdDataModel, RpdDataModelProperty, RpdServerEventTypes } from "~/types";
1
+ import { CreateEntityOptions, GetDataAccessorOptions, GetModelOptions, IDatabaseConfig, IQueryBuilder, IRpdDataAccessor, RapidServerConfig, RpdApplicationConfig, RpdDataModel, RpdDataModelProperty, RpdServerEventTypes } from "~/types";
2
2
  import { IPluginActionHandler, ActionHandler, ActionHandlerContext } from "./actionHandler";
3
3
  import { Next, RouteContext } from "./routeContext";
4
4
  import EntityManager from "~/dataAccess/entityManager";
@@ -48,6 +48,7 @@ export interface IRpdServer {
48
48
  ): void;
49
49
  handleRequest(request: Request, next: Next): Promise<Response>;
50
50
  beforeRunRouteActions(handlerContext: ActionHandlerContext): Promise<void>;
51
+ beforeCreateEntity(model: RpdDataModel, options: CreateEntityOptions): Promise<void>;
51
52
  }
52
53
 
53
54
 
@@ -139,4 +140,6 @@ export interface RapidPlugin {
139
140
  onPrepareRouteContext?: (server: IRpdServer, routeContext: RouteContext) => Promise<any>;
140
141
  /** 在接收到HTTP请求,执行 actions 前调用。 */
141
142
  beforeRunRouteActions?: (server: IRpdServer, handlerContext: ActionHandlerContext) => Promise<any>;
143
+ /** 在创建实体前调用。 */
144
+ beforeCreateEntity?: (server: IRpdServer, model: RpdDataModel, options: CreateEntityOptions) => Promise<any>;
142
145
  }
@@ -733,6 +733,9 @@ export default class EntityManager<TEntity=any> {
733
733
 
734
734
  async createEntity(options: CreateEntityOptions, plugin?: RapidPlugin): Promise<TEntity> {
735
735
  const model = this.getModel();
736
+
737
+ await this.#server.beforeCreateEntity(model, options);
738
+
736
739
  const newEntity = await createEntity(this.#server, this.#dataAccessor, options);
737
740
 
738
741
  this.#server.emitEvent(
package/src/index.ts CHANGED
@@ -17,6 +17,7 @@ export * as bootstrapApplicationConfig from "./bootstrapApplicationConfig";
17
17
  export { default as MetaManagePlugin } from "./plugins/metaManage/MetaManagePlugin";
18
18
  export { default as DataManagePlugin } from "./plugins/dataManage/DataManagePlugin";
19
19
  export { default as RouteManagePlugin } from "./plugins/routeManage/RouteManagePlugin";
20
+ export { default as SequencePlugin } from "./plugins/sequence/SequencePlugin";
20
21
  export { default as WebhooksPlugin } from "./plugins/webhooks/WebhooksPlugin";
21
22
  export { default as AuthPlugin } from "./plugins/auth/AuthPlugin";
22
23
  export { default as FileManagePlugin } from "./plugins/fileManage/FileManagePlugin";
@@ -0,0 +1,58 @@
1
+ import bcrypt from "bcrypt";
2
+ import { ActionHandlerContext } from "~/core/actionHandler";
3
+ import { RapidPlugin } from "~/core/server";
4
+
5
+ export const code = "changePassword";
6
+
7
+ export async function handler(
8
+ plugin: RapidPlugin,
9
+ ctx: ActionHandlerContext,
10
+ options: any,
11
+ ) {
12
+ const { server, input, routerContext } = ctx;
13
+ const { response } = routerContext;
14
+ const { id, oldPassword, newPassword } = input;
15
+
16
+ const userId = routerContext.state.userId;
17
+ if (!userId) {
18
+ ctx.status = 401;
19
+ ctx.output = {
20
+ error: {
21
+ message: "You are not signed in."
22
+ }
23
+ }
24
+ return;
25
+ }
26
+
27
+ const userDataAccessor = server.getDataAccessor({
28
+ singularCode: "oc_user",
29
+ });
30
+
31
+ const user = await userDataAccessor.findOne({
32
+ filters: [
33
+ {
34
+ operator: "eq",
35
+ field: "id",
36
+ value: userId,
37
+ }
38
+ ]
39
+ });
40
+
41
+ if (!user) {
42
+ throw new Error("User not found.");
43
+ }
44
+
45
+ const isMatch = await bcrypt.compare(oldPassword, user.password);
46
+ if (!isMatch) {
47
+ throw new Error("旧密码错误。");
48
+ }
49
+
50
+ const saltRounds = 10;
51
+ const passwordHash = await bcrypt.hash(newPassword, saltRounds);
52
+
53
+ await userDataAccessor.updateById(user.id, {
54
+ password: passwordHash,
55
+ });
56
+
57
+ ctx.output = {};
58
+ }
@@ -1,3 +1,4 @@
1
+ import bcrypt from "bcrypt";
1
2
  import { setCookie } from "~/deno-std/http/cookie";
2
3
  import { createJwt } from "~/utilities/jwtUtility";
3
4
  import { ActionHandlerContext } from "~/core/actionHandler";
@@ -34,7 +35,12 @@ export async function handler(
34
35
  });
35
36
 
36
37
  if (!user) {
37
- throw new Error("Wrong account or password.");
38
+ throw new Error("用户名或密码错误。");
39
+ }
40
+
41
+ const isMatch = await bcrypt.compare(password, user.password);
42
+ if (!isMatch) {
43
+ throw new Error("用户名或密码错误。");
38
44
  }
39
45
 
40
46
  const secretKey = Buffer.from(server.config.jwtKey, "base64");
@@ -2,9 +2,11 @@ import { IPluginActionHandler } from "~/core/actionHandler";
2
2
  import * as createSession from "./createSession";
3
3
  import * as deleteSession from "./deleteSession";
4
4
  import * as getMyProfile from "./getMyProfile";
5
+ import * as resetPassword from "./resetPassword";
5
6
 
6
7
  export default [
7
8
  createSession,
8
9
  deleteSession,
9
10
  getMyProfile,
11
+ resetPassword,
10
12
  ] satisfies IPluginActionHandler[];
@@ -0,0 +1,42 @@
1
+ import bcrypt from "bcrypt";
2
+ import { ActionHandlerContext } from "~/core/actionHandler";
3
+ import { RapidPlugin } from "~/core/server";
4
+
5
+ export const code = "resetPassword";
6
+
7
+ export async function handler(
8
+ plugin: RapidPlugin,
9
+ ctx: ActionHandlerContext,
10
+ options: any,
11
+ ) {
12
+ const { server, input, routerContext } = ctx;
13
+ const { response } = routerContext;
14
+ const { userId, password } = input;
15
+
16
+ const userDataAccessor = server.getDataAccessor({
17
+ singularCode: "oc_user",
18
+ });
19
+
20
+ const user = await userDataAccessor.findOne({
21
+ filters: [
22
+ {
23
+ operator: "eq",
24
+ field: "id",
25
+ value: userId,
26
+ }
27
+ ]
28
+ });
29
+
30
+ if (!user) {
31
+ throw new Error("User not found.");
32
+ }
33
+
34
+ const saltRounds = 10;
35
+ const passwordHash = await bcrypt.hash(password, saltRounds);
36
+
37
+ await userDataAccessor.updateById(user.id, {
38
+ password: passwordHash,
39
+ });
40
+
41
+ ctx.output = {};
42
+ }
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Sequence plugin
3
+ */
4
+
5
+ import {
6
+ CreateEntityOptions,
7
+ RpdApplicationConfig,
8
+ RpdDataModel,
9
+ RpdDataModelProperty,
10
+ } from "~/types";
11
+ import { IRpdServer, RapidPlugin, RpdConfigurationItemOptions, RpdServerPluginConfigurableTargetOptions, RpdServerPluginExtendingAbilities } from "~/core/server";
12
+
13
+ import pluginActionHandlers from "./actionHandlers";
14
+ import pluginModels from "./models";
15
+ import pluginRoutes from "./routes";
16
+ import { RouteContext } from "~/core/routeContext";
17
+ import { PropertySequenceConfig } from "./sequence-types";
18
+ import { isNull, isUndefined } from "lodash";
19
+ import { generateSn } from "./SequenceService";
20
+
21
+
22
+ class SequencePlugin implements RapidPlugin {
23
+ get code(): string {
24
+ return "sequencePlugin";
25
+ }
26
+
27
+ get description(): string {
28
+ return null;
29
+ }
30
+
31
+ get extendingAbilities(): RpdServerPluginExtendingAbilities[] {
32
+ return [];
33
+ }
34
+
35
+ get configurableTargets(): RpdServerPluginConfigurableTargetOptions[] {
36
+ return [];
37
+ }
38
+
39
+ get configurations(): RpdConfigurationItemOptions[] {
40
+ return [];
41
+ }
42
+
43
+ async registerActionHandlers(server: IRpdServer): Promise<any> {
44
+ for (const actionHandler of pluginActionHandlers) {
45
+ server.registerActionHandler(this, actionHandler);
46
+ }
47
+ }
48
+
49
+ async configureModels(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any> {
50
+ server.appendApplicationConfig({ models: pluginModels });
51
+ }
52
+
53
+ async configureRoutes(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any> {
54
+ server.appendApplicationConfig({ routes: pluginRoutes });
55
+ }
56
+
57
+ async onApplicationLoaded(server: IRpdServer, applicationConfig: RpdApplicationConfig) {
58
+ const models = server.getApplicationConfig().models;
59
+ for (const model of models) {
60
+ for (const property of model.properties) {
61
+ const sequenceConfig: PropertySequenceConfig = property.config?.sequence;
62
+ if (sequenceConfig) {
63
+ const ruleCode = getSequenceRuleCode(model, property);
64
+ const ruleConfig = sequenceConfig.ruleConfig;
65
+
66
+ const sequenceRuleDataAccessor = server.getDataAccessor({
67
+ singularCode: "sequence_rule",
68
+ });
69
+ const sequenceRule = await sequenceRuleDataAccessor.findOne({
70
+ filters: [
71
+ {
72
+ operator: "eq",
73
+ field: "code",
74
+ value: ruleCode,
75
+ },
76
+ ],
77
+ });
78
+
79
+ if (sequenceRule) {
80
+ if (JSON.stringify(sequenceRule.config) !== JSON.stringify(ruleConfig)) {
81
+ await sequenceRuleDataAccessor.updateById(sequenceRule.id, {
82
+ config: ruleConfig,
83
+ });
84
+ }
85
+ } else {
86
+ await sequenceRuleDataAccessor.create({
87
+ code: ruleCode,
88
+ config: ruleConfig,
89
+ });
90
+ }
91
+ }
92
+ }
93
+ }
94
+ }
95
+
96
+ async beforeCreateEntity(server: IRpdServer, model: RpdDataModel, options: CreateEntityOptions) {
97
+ debugger;
98
+ const entity = options.entity;
99
+ for (const property of model.properties) {
100
+ const sequenceConfig: PropertySequenceConfig = property.config?.sequence;
101
+ const propertyValue = entity[property.code];
102
+ if (sequenceConfig &&
103
+ sequenceConfig.autoGenerate &&
104
+ (isUndefined(propertyValue) || isNull(propertyValue))
105
+ ) {
106
+ const ruleCode = getSequenceRuleCode(model, property);
107
+ const sns = await generateSn(server, {
108
+ ruleCode,
109
+ amount: 1,
110
+ parameters: entity,
111
+ });
112
+ entity[property.code] = sns[0];
113
+ }
114
+ }
115
+ }
116
+ }
117
+
118
+ function getSequenceRuleCode(model: RpdDataModel, property: RpdDataModelProperty) {
119
+ return `propertyAutoGenerate.${model.namespace}.${model.singularCode}.${property.code}`;
120
+ }
121
+
122
+ export default SequencePlugin;