@flowerforce/flowerbase 1.0.3-beta.2 → 1.0.3-beta.4

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 (85) hide show
  1. package/dist/auth/plugins/jwt.d.ts.map +1 -1
  2. package/dist/auth/plugins/jwt.js +2 -1
  3. package/dist/auth/providers/custom-function/controller.d.ts +8 -0
  4. package/dist/auth/providers/custom-function/controller.d.ts.map +1 -0
  5. package/dist/auth/providers/custom-function/controller.js +83 -0
  6. package/dist/auth/providers/custom-function/dtos.d.ts +15 -0
  7. package/dist/auth/providers/custom-function/dtos.d.ts.map +1 -0
  8. package/dist/auth/providers/custom-function/dtos.js +2 -0
  9. package/dist/auth/providers/custom-function/schema.d.ts +31 -0
  10. package/dist/auth/providers/custom-function/schema.d.ts.map +1 -0
  11. package/dist/auth/providers/custom-function/schema.js +25 -0
  12. package/dist/auth/providers/local-userpass/controller.d.ts.map +1 -1
  13. package/dist/auth/providers/local-userpass/controller.js +31 -59
  14. package/dist/auth/utils.d.ts +9 -0
  15. package/dist/auth/utils.d.ts.map +1 -1
  16. package/dist/constants.d.ts +9 -0
  17. package/dist/constants.d.ts.map +1 -1
  18. package/dist/constants.js +13 -4
  19. package/dist/features/endpoints/utils.d.ts.map +1 -1
  20. package/dist/features/endpoints/utils.js +23 -4
  21. package/dist/features/functions/queue.d.ts +7 -0
  22. package/dist/features/functions/queue.d.ts.map +1 -0
  23. package/dist/features/functions/queue.js +69 -0
  24. package/dist/features/triggers/utils.d.ts.map +1 -1
  25. package/dist/features/triggers/utils.js +22 -6
  26. package/dist/services/auth/index.d.ts +4 -0
  27. package/dist/services/auth/index.d.ts.map +1 -0
  28. package/dist/services/auth/index.js +14 -0
  29. package/dist/services/auth/model.d.ts +12 -0
  30. package/dist/services/auth/model.d.ts.map +1 -0
  31. package/dist/services/auth/model.js +2 -0
  32. package/dist/services/aws/index.d.ts.map +1 -1
  33. package/dist/services/aws/index.js +7 -10
  34. package/dist/services/index.d.ts +1 -0
  35. package/dist/services/index.d.ts.map +1 -1
  36. package/dist/services/index.js +2 -0
  37. package/dist/services/mongodb-atlas/index.d.ts.map +1 -1
  38. package/dist/services/mongodb-atlas/index.js +28 -5
  39. package/dist/services/mongodb-atlas/utils.d.ts +17 -1
  40. package/dist/services/mongodb-atlas/utils.d.ts.map +1 -1
  41. package/dist/services/mongodb-atlas/utils.js +24 -11
  42. package/dist/shared/handleUserRegistration.d.ts +11 -0
  43. package/dist/shared/handleUserRegistration.d.ts.map +1 -0
  44. package/dist/shared/handleUserRegistration.js +62 -0
  45. package/dist/shared/models/handleUserRegistration.model.d.ts +16 -0
  46. package/dist/shared/models/handleUserRegistration.model.d.ts.map +1 -0
  47. package/dist/shared/models/handleUserRegistration.model.js +2 -0
  48. package/dist/state.d.ts.map +1 -1
  49. package/dist/state.js +3 -1
  50. package/dist/utils/context/helpers.d.ts +15 -1
  51. package/dist/utils/context/helpers.d.ts.map +1 -1
  52. package/dist/utils/context/helpers.js +2 -1
  53. package/dist/utils/context/index.d.ts +1 -1
  54. package/dist/utils/context/index.d.ts.map +1 -1
  55. package/dist/utils/context/index.js +31 -22
  56. package/dist/utils/context/interface.d.ts +6 -1
  57. package/dist/utils/context/interface.d.ts.map +1 -1
  58. package/dist/utils/initializer/registerPlugins.d.ts.map +1 -1
  59. package/dist/utils/initializer/registerPlugins.js +11 -3
  60. package/dist/utils/roles/helpers.js +1 -1
  61. package/package.json +1 -1
  62. package/src/auth/plugins/jwt.ts +4 -2
  63. package/src/auth/providers/custom-function/controller.ts +94 -0
  64. package/src/auth/providers/custom-function/dtos.ts +16 -0
  65. package/src/auth/providers/custom-function/schema.ts +25 -0
  66. package/src/auth/providers/local-userpass/controller.ts +45 -71
  67. package/src/auth/utils.ts +10 -0
  68. package/src/constants.ts +14 -2
  69. package/src/features/endpoints/utils.ts +26 -6
  70. package/src/features/functions/queue.ts +48 -0
  71. package/src/features/triggers/utils.ts +11 -6
  72. package/src/services/auth/index.ts +12 -0
  73. package/src/services/auth/model.ts +13 -0
  74. package/src/services/aws/index.ts +10 -11
  75. package/src/services/index.ts +2 -0
  76. package/src/services/mongodb-atlas/index.ts +61 -26
  77. package/src/services/mongodb-atlas/utils.ts +98 -59
  78. package/src/shared/handleUserRegistration.ts +64 -0
  79. package/src/shared/models/handleUserRegistration.model.ts +20 -0
  80. package/src/state.ts +4 -1
  81. package/src/utils/context/helpers.ts +6 -1
  82. package/src/utils/context/index.ts +46 -29
  83. package/src/utils/context/interface.ts +5 -1
  84. package/src/utils/initializer/registerPlugins.ts +9 -1
  85. package/src/utils/roles/helpers.ts +1 -1
@@ -16,6 +16,7 @@ exports.GenerateContext = GenerateContext;
16
16
  const node_module_1 = require("node:module");
17
17
  const vm_1 = __importDefault(require("vm"));
18
18
  const bson_1 = require("bson");
19
+ const state_1 = require("../../state");
19
20
  const helpers_1 = require("./helpers");
20
21
  /**
21
22
  * > Used to generate the current context
@@ -29,28 +30,36 @@ const helpers_1 = require("./helpers");
29
30
  * @param services -> the list of all services
30
31
  */
31
32
  function GenerateContext(_a) {
32
- return __awaiter(this, arguments, void 0, function* ({ args, app, rules, user, currentFunction, functionsList, services, runAsSystem }) {
33
- var _b, _c;
34
- const contextFunction = Object.assign({ run_as_system: runAsSystem }, currentFunction);
35
- const contextData = (0, helpers_1.generateContextData)({
36
- user,
37
- services,
38
- app,
39
- rules,
40
- currentFunction: contextFunction,
41
- functionsList,
42
- GenerateContext,
43
- runAsSystem
33
+ return __awaiter(this, arguments, void 0, function* ({ args, app, rules, user, currentFunction, functionsList, services, runAsSystem, deserializeArgs = true, enqueue, request }) {
34
+ const functionsQueue = state_1.StateManager.select("functionsQueue");
35
+ const functionToRun = Object.assign({ run_as_system: runAsSystem }, currentFunction);
36
+ const run = () => __awaiter(this, void 0, void 0, function* () {
37
+ var _a, _b;
38
+ const contextData = (0, helpers_1.generateContextData)({
39
+ user,
40
+ services,
41
+ app,
42
+ rules,
43
+ currentFunction: functionToRun,
44
+ functionsList,
45
+ GenerateContext,
46
+ request
47
+ });
48
+ try {
49
+ const entryFile = (_b = (_a = require.main) === null || _a === void 0 ? void 0 : _a.filename) !== null && _b !== void 0 ? _b : process.cwd();
50
+ const customRequire = (0, node_module_1.createRequire)(entryFile);
51
+ vm_1.default.runInContext(functionToRun.code, vm_1.default.createContext(Object.assign(Object.assign({}, contextData), { require: customRequire, exports,
52
+ module, __filename: __filename, __dirname: __dirname })));
53
+ }
54
+ catch (e) {
55
+ console.log(e);
56
+ }
57
+ if (deserializeArgs) {
58
+ return yield module.exports(...bson_1.EJSON.deserialize(args));
59
+ }
60
+ return yield module.exports(...args);
44
61
  });
45
- try {
46
- const entryFile = (_c = (_b = require.main) === null || _b === void 0 ? void 0 : _b.filename) !== null && _c !== void 0 ? _c : process.cwd();
47
- const customRequire = (0, node_module_1.createRequire)(entryFile);
48
- vm_1.default.runInContext(contextFunction.code, vm_1.default.createContext(Object.assign(Object.assign({}, contextData), { require: customRequire, exports,
49
- module, __filename: __filename, __dirname: __dirname })));
50
- }
51
- catch (e) {
52
- console.log(e);
53
- }
54
- return yield module.exports(...bson_1.EJSON.deserialize(args));
62
+ const res = yield functionsQueue.add(run, enqueue);
63
+ return res;
55
64
  });
56
65
  }
@@ -1,4 +1,4 @@
1
- import { FastifyInstance } from 'fastify';
1
+ import { FastifyInstance, FastifyRequest } from 'fastify';
2
2
  import { Arguments, User } from '../../auth/dtos';
3
3
  import { Function, Functions } from '../../features/functions/interface';
4
4
  import { Rules } from '../../features/rules/interface';
@@ -12,8 +12,13 @@ export interface GenerateContextParams {
12
12
  services: Services;
13
13
  args: Arguments;
14
14
  runAsSystem?: boolean;
15
+ deserializeArgs?: boolean;
16
+ enqueue?: boolean;
17
+ request?: ContextRequest;
15
18
  }
19
+ type ContextRequest = Pick<FastifyRequest, "ips" | "host" | "hostname" | "url" | "method" | "ip" | "id">;
16
20
  export interface GenerateContextDataParams extends Omit<GenerateContextParams, 'args'> {
17
21
  GenerateContext: (params: GenerateContextParams) => Promise<void>;
18
22
  }
23
+ export {};
19
24
  //# sourceMappingURL=interface.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/utils/context/interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AACzC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAA;AACxE,OAAO,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAA;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAEnD,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,eAAe,CAAA;IACpB,eAAe,EAAE,QAAQ,CAAA;IACzB,aAAa,EAAE,SAAS,CAAA;IACxB,KAAK,EAAE,KAAK,CAAA;IACZ,IAAI,EAAE,IAAI,CAAA;IACV,QAAQ,EAAE,QAAQ,CAAA;IAClB,IAAI,EAAE,SAAS,CAAA;IACf,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED,MAAM,WAAW,yBAA0B,SAAQ,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACpF,eAAe,EAAE,CAAC,MAAM,EAAE,qBAAqB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAClE"}
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/utils/context/interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AACzD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAA;AACxE,OAAO,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAA;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAEnD,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,eAAe,CAAA;IACpB,eAAe,EAAE,QAAQ,CAAA;IACzB,aAAa,EAAE,SAAS,CAAA;IACxB,KAAK,EAAE,KAAK,CAAA;IACZ,IAAI,EAAE,IAAI,CAAA;IACV,QAAQ,EAAE,QAAQ,CAAA;IAClB,IAAI,EAAE,SAAS,CAAA;IACf,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,OAAO,CAAC,EAAE,cAAc,CAAA;CACzB;AAED,KAAK,cAAc,GAAG,IAAI,CAAC,cAAc,EAAE,KAAK,GAAG,MAAM,GAAG,UAAU,GAAG,KAAK,GAAG,QAAQ,GAAG,IAAI,GAAG,IAAI,CAAC,CAAA;AACxG,MAAM,WAAW,yBAA0B,SAAQ,IAAI,CAAC,qBAAqB,EAAE,MAAM,CAAC;IACpF,eAAe,EAAE,CAAC,MAAM,EAAE,qBAAqB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAClE"}
@@ -1 +1 @@
1
- {"version":3,"file":"registerPlugins.d.ts","sourceRoot":"","sources":["../../../src/utils/initializer/registerPlugins.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAKzC,OAAO,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAA;AAE9D,KAAK,gBAAgB,GAAG,eAAe,CAAC,UAAU,CAAC,CAAA;AAGnD,KAAK,qBAAqB,GAAG;IAC3B,QAAQ,EAAE,gBAAgB,CAAA;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,SAAS,CAAA;CACzB,CAAA;AAQD;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAAU,oDAKnC,qBAAqB,kBAoBvB,CAAA"}
1
+ {"version":3,"file":"registerPlugins.d.ts","sourceRoot":"","sources":["../../../src/utils/initializer/registerPlugins.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAMzC,OAAO,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAA;AAE9D,KAAK,gBAAgB,GAAG,eAAe,CAAC,UAAU,CAAC,CAAA;AAGnD,KAAK,qBAAqB,GAAG;IAC3B,QAAQ,EAAE,gBAAgB,CAAA;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,SAAS,CAAA;CACzB,CAAA;AAQD;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,GAAU,oDAKnC,qBAAqB,kBAoBvB,CAAA"}
@@ -17,7 +17,8 @@ const cors_1 = __importDefault(require("@fastify/cors"));
17
17
  const mongodb_1 = __importDefault(require("@fastify/mongodb"));
18
18
  const controller_1 = require("../../auth/controller");
19
19
  const jwt_1 = __importDefault(require("../../auth/plugins/jwt"));
20
- const controller_2 = require("../../auth/providers/local-userpass/controller");
20
+ const controller_2 = require("../../auth/providers/custom-function/controller");
21
+ const controller_3 = require("../../auth/providers/local-userpass/controller");
21
22
  const constants_1 = require("../../constants");
22
23
  /**
23
24
  * > Used to register all plugins
@@ -50,7 +51,7 @@ const registerPlugins = (_a) => __awaiter(void 0, [_a], void 0, function* ({ reg
50
51
  });
51
52
  exports.registerPlugins = registerPlugins;
52
53
  /**
53
- * > Used to generate the register congig
54
+ * > Used to generate the register config
54
55
  * @param mongodbUrl -> the database connection string
55
56
  * @param jwtSecret -> connection jwt
56
57
  * @testable
@@ -87,10 +88,17 @@ const getRegisterConfig = (_a) => __awaiter(void 0, [_a], void 0, function* ({ m
87
88
  },
88
89
  {
89
90
  pluginName: 'localUserPassController',
90
- plugin: controller_2.localUserPassController,
91
+ plugin: controller_3.localUserPassController,
91
92
  options: {
92
93
  prefix: `${constants_1.API_VERSION}/app/:appId/auth/providers/local-userpass`
93
94
  }
95
+ },
96
+ {
97
+ pluginName: 'customFunctionController',
98
+ plugin: controller_2.customFunctionController,
99
+ options: {
100
+ prefix: `${constants_1.API_VERSION}/app/:appId/auth/providers/custom-function`
101
+ }
94
102
  }
95
103
  ];
96
104
  });
@@ -39,7 +39,7 @@ const evaluateComplexExpression = (condition, params, user) => __awaiter(void 0,
39
39
  const response = yield (0, context_1.GenerateContext)({
40
40
  args: [params.cursor],
41
41
  app,
42
- rules: {},
42
+ rules: state_1.StateManager.select("rules"),
43
43
  user,
44
44
  currentFunction,
45
45
  functionsList,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowerforce/flowerbase",
3
- "version": "1.0.3-beta.2",
3
+ "version": "1.0.3-beta.4",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -32,9 +32,11 @@ export default fp(async function (fastify, opts: Options) {
32
32
 
33
33
  fastify.decorate('createAccessToken', function (user: WithId<Document>) {
34
34
  const id = user._id.toString()
35
+ const userDataId = user.user_data._id.toString()
36
+
35
37
  const user_data = {
36
- _id: id,
37
- id,
38
+ _id: userDataId,
39
+ id: userDataId,
38
40
  ...user.user_data
39
41
  }
40
42
  return this.jwt.sign(
@@ -0,0 +1,94 @@
1
+ import { ObjectId } from 'bson'
2
+ import { FastifyInstance } from 'fastify'
3
+ import { AUTH_CONFIG } from '../../../constants'
4
+ import { StateManager } from '../../../state'
5
+ import { GenerateContext } from '../../../utils/context'
6
+ import {
7
+ AUTH_ENDPOINTS,
8
+ } from '../../utils'
9
+ import {
10
+ LoginDto
11
+ } from './dtos'
12
+ import { LOGIN_SCHEMA } from './schema'
13
+
14
+ /**
15
+ * Controller for handling custom function login.
16
+ * @testable
17
+ * @param {FastifyInstance} app - The Fastify instance.
18
+ */
19
+ export async function customFunctionController(app: FastifyInstance) {
20
+
21
+ const functionsList = StateManager.select('functions')
22
+ const services = StateManager.select('services')
23
+
24
+ /**
25
+ * Endpoint for user login.
26
+ *
27
+ * @route {POST} /login
28
+ * @param {LoginDto} req - The request object with login data.
29
+ * @returns {Promise<Object>} A promise resolving with access and refresh tokens.
30
+ */
31
+ app.post<LoginDto>(
32
+ AUTH_ENDPOINTS.LOGIN,
33
+ {
34
+ schema: LOGIN_SCHEMA
35
+ },
36
+ async function (req) {
37
+ const { providers } = AUTH_CONFIG
38
+ const authFunctionName = providers["custom-function"].authFunctionName
39
+
40
+ if (!authFunctionName || !functionsList[authFunctionName]) {
41
+ throw new Error("Missing Auth Function")
42
+ }
43
+
44
+ const {
45
+ ips,
46
+ host,
47
+ hostname,
48
+ url,
49
+ method,
50
+ ip,
51
+ id
52
+ } = req
53
+
54
+ const res = await GenerateContext({
55
+ args: [
56
+ req.body
57
+ ],
58
+ app,
59
+ rules: {},
60
+ user: {},
61
+ currentFunction: functionsList[authFunctionName],
62
+ functionsList,
63
+ services,
64
+ request: {
65
+ ips,
66
+ host,
67
+ hostname,
68
+ url,
69
+ method,
70
+ ip,
71
+ id
72
+ }
73
+ })
74
+
75
+ const currentUserData = {
76
+ _id: new ObjectId(res.id),
77
+ user_data: {
78
+ _id: new ObjectId(res.id),
79
+ }
80
+ }
81
+ if (res.id) {
82
+ return {
83
+ access_token: this.createAccessToken(currentUserData),
84
+ refresh_token: this.createRefreshToken(currentUserData),
85
+ device_id: '',
86
+ user_id: res.id
87
+ }
88
+ }
89
+
90
+ throw new Error("Authentication Failed")
91
+ }
92
+ )
93
+
94
+ }
@@ -0,0 +1,16 @@
1
+ export type LoginUserDto = {
2
+ username: string
3
+ password: string
4
+ }
5
+
6
+ export type LoginSuccessDto = {
7
+ access_token: string
8
+ device_id: string
9
+ refresh_token: string
10
+ user_id: string
11
+ }
12
+
13
+ export interface LoginDto {
14
+ Body: LoginUserDto
15
+ Reply: LoginSuccessDto
16
+ }
@@ -0,0 +1,25 @@
1
+ export const LOGIN_SCHEMA = {
2
+ body: {
3
+ type: 'object',
4
+ properties:
5
+ {
6
+ apiKey: { type: 'string' },
7
+ options: {
8
+ type: "object",
9
+ properties: {
10
+ device: {
11
+ type: "object",
12
+ properties: {
13
+ sdkVersion: { type: 'string' },
14
+ platform: { type: 'string' },
15
+ platformVersion: { type: 'string' }
16
+ }
17
+ }
18
+
19
+ }
20
+ },
21
+
22
+ },
23
+ required: ['apiKey', 'options']
24
+ }
25
+ }
@@ -2,6 +2,7 @@ import sendGrid from '@sendgrid/mail'
2
2
  import { FastifyInstance } from 'fastify'
3
3
  import { AUTH_CONFIG, DB_NAME } from '../../../constants'
4
4
  import { services } from '../../../services'
5
+ import handleUserRegistration from '../../../shared/handleUserRegistration'
5
6
  import { StateManager } from '../../../state'
6
7
  import { GenerateContext } from '../../../utils/context'
7
8
  import { comparePassword, generateToken, hashPassword } from '../../../utils/crypto'
@@ -11,7 +12,6 @@ import {
11
12
  CONFIRM_RESET_SCHEMA,
12
13
  getMailConfig,
13
14
  LOGIN_SCHEMA,
14
- PROVIDER_TYPE,
15
15
  REGISTRATION_SCHEMA,
16
16
  RESET_SCHEMA
17
17
  } from '../../utils'
@@ -28,10 +28,14 @@ import {
28
28
  * @param {FastifyInstance} app - The Fastify instance.
29
29
  */
30
30
  export async function localUserPassController(app: FastifyInstance) {
31
-
32
31
  const functionsList = StateManager.select('functions')
33
32
 
34
- const { authCollection, userCollection, user_id_field, on_user_creation_function_name } = AUTH_CONFIG
33
+ const {
34
+ authCollection,
35
+ userCollection,
36
+ user_id_field,
37
+ on_user_creation_function_name
38
+ } = AUTH_CONFIG
35
39
  const db = app.mongo.client.db(DB_NAME)
36
40
 
37
41
  /**
@@ -47,53 +51,12 @@ export async function localUserPassController(app: FastifyInstance) {
47
51
  {
48
52
  schema: REGISTRATION_SCHEMA
49
53
  },
50
- async function (req, res) {
51
- const { email, password } = req.body
52
- const hashedPassword = await hashPassword(password)
53
-
54
- const existingUser = await db.collection(authCollection!).findOne({
55
- email
56
- })
57
-
58
- if (existingUser) {
59
- res.status(409)
60
- return {
61
- error: 'This email address is already used'
62
- }
63
- }
64
-
65
- const result = await db.collection(authCollection!).insertOne({
66
- email: email,
67
- password: hashedPassword,
68
- status: 'pending',
69
- custom_data: {
70
- // TODO da aggiungere in fase di registrazione utente, funzionalità utile che realm non permetteva
71
- }
72
- })
73
-
74
- await db?.collection(authCollection!).updateOne(
75
- {
76
- email: email
77
- },
78
- {
79
- $set: {
80
- identities: [
81
- {
82
- id: result?.insertedId.toString(),
83
- provider_id: result?.insertedId.toString(),
84
- provider_type: PROVIDER_TYPE,
85
- provider_data: { email }
86
- }
87
- ]
88
- }
89
- }
90
- )
54
+ async (req, res) => {
91
55
 
92
- res.status(201)
56
+ const result = await handleUserRegistration(app, { run_as_system: true })({ email: req.body.email.toLowerCase(), password: req.body.password })
93
57
 
94
- return {
95
- userId: result?.insertedId
96
- }
58
+ res?.status(201)
59
+ return { userId: result?.insertedId.toString() }
97
60
  }
98
61
  )
99
62
 
@@ -110,32 +73,37 @@ export async function localUserPassController(app: FastifyInstance) {
110
73
  schema: LOGIN_SCHEMA
111
74
  },
112
75
  async function (req) {
113
- const storedUser = await db.collection(authCollection!).findOne({
76
+ const authUser = await db.collection(authCollection!).findOne({
114
77
  email: req.body.username
115
78
  })
116
79
 
117
- if (!storedUser) {
80
+ if (!authUser) {
118
81
  throw new Error(AUTH_ERRORS.INVALID_CREDENTIALS)
119
82
  }
120
83
 
121
84
  const passwordMatches = await comparePassword(
122
85
  req.body.password,
123
- storedUser.password
86
+ authUser.password
124
87
  )
125
88
 
126
89
  if (!passwordMatches) {
127
90
  throw new Error(AUTH_ERRORS.INVALID_CREDENTIALS)
128
91
  }
129
92
 
130
- const user = user_id_field && userCollection
131
- ? (await db!.collection(userCollection).findOne({ [user_id_field]: storedUser._id.toString() }))
132
- : {}
93
+ const user =
94
+ user_id_field && userCollection
95
+ ? await db!
96
+ .collection(userCollection)
97
+ .findOne({ [user_id_field]: authUser._id.toString() })
98
+ : {}
99
+ delete authUser?.password
133
100
 
134
- const userWithCustomData = { ...storedUser, user_data: user }
101
+ const userWithCustomData = { ...authUser, user_data: user, id: authUser._id.toString() }
135
102
 
136
- if (storedUser && storedUser.status === 'pending') {
103
+ if (authUser && authUser.status === 'pending') {
137
104
  try {
138
- await db?.collection(authCollection!).updateOne({ _id: storedUser._id },
105
+ await db?.collection(authCollection!).updateOne(
106
+ { _id: authUser._id },
139
107
  {
140
108
  $set: {
141
109
  status: 'confirmed'
@@ -143,29 +111,35 @@ export async function localUserPassController(app: FastifyInstance) {
143
111
  }
144
112
  )
145
113
  } catch (error) {
146
- console.log(">>> 🚀 ~ localUserPassController ~ error:", error)
114
+ console.log('>>> 🚀 ~ localUserPassController ~ error:', error)
147
115
  }
148
116
  }
149
117
 
150
- if (storedUser && storedUser.status === 'pending' && on_user_creation_function_name && functionsList[on_user_creation_function_name]) {
151
- delete storedUser?.password
118
+ if (
119
+ authUser &&
120
+ authUser.status === 'pending' &&
121
+ on_user_creation_function_name &&
122
+ functionsList[on_user_creation_function_name]
123
+ ) {
152
124
  try {
153
125
  await GenerateContext({
154
- args: [{
155
- operationType: 'CREATE',
156
- providers: 'local-userpass',
157
- user,
158
- time: new Date().getTime()
159
- }],
126
+ args: [
127
+ {
128
+ operationType: 'CREATE',
129
+ providers: 'local-userpass',
130
+ user: userWithCustomData,
131
+ time: new Date().getTime()
132
+ }
133
+ ],
160
134
  app,
161
135
  rules: {},
162
- user: undefined,
136
+ user: userWithCustomData,
163
137
  currentFunction: functionsList[on_user_creation_function_name],
164
138
  functionsList,
165
139
  services
166
140
  })
167
141
  } catch (error) {
168
- console.log("🚀 ~ error:", error)
142
+ console.log('localUserPassController - /login - GenerateContext - CATCH:', error)
169
143
  }
170
144
  }
171
145
 
@@ -173,7 +147,7 @@ export async function localUserPassController(app: FastifyInstance) {
173
147
  access_token: this.createAccessToken(userWithCustomData),
174
148
  refresh_token: this.createRefreshToken(userWithCustomData),
175
149
  device_id: '',
176
- user_id: storedUser._id.toString()
150
+ user_id: authUser._id.toString()
177
151
  }
178
152
  }
179
153
  )
@@ -193,11 +167,11 @@ export async function localUserPassController(app: FastifyInstance) {
193
167
  async function (req) {
194
168
  const { resetPasswordCollection, resetPasswordConfig } = AUTH_CONFIG
195
169
  const email = req.body.email
196
- const storedUser = await db.collection(authCollection!).findOne({
170
+ const authUser = await db.collection(authCollection!).findOne({
197
171
  email
198
172
  })
199
173
 
200
- if (!storedUser) {
174
+ if (!authUser) {
201
175
  throw new Error(AUTH_ERRORS.INVALID_CREDENTIALS)
202
176
  }
203
177
 
package/src/auth/utils.ts CHANGED
@@ -66,6 +66,7 @@ export interface AuthConfig {
66
66
  auth_collection?: string
67
67
  'api-key': ApiKey
68
68
  'local-userpass': LocalUserpass
69
+ 'custom-function': CustomFunction
69
70
  }
70
71
 
71
72
  interface ApiKey {
@@ -80,6 +81,15 @@ interface LocalUserpass {
80
81
  config: Config
81
82
  }
82
83
 
84
+ interface CustomFunction {
85
+ name: "custom-function",
86
+ type: "custom-function",
87
+ disabled: boolean,
88
+ config: {
89
+ "authFunctionName": string
90
+ }
91
+ }
92
+
83
93
  export interface Config {
84
94
  autoConfirm: boolean
85
95
  resetFunctionName: string
package/src/constants.ts CHANGED
@@ -20,11 +20,23 @@ export const DEFAULT_CONFIG = {
20
20
  export const API_VERSION = `/api/client/${DEFAULT_CONFIG.API_VERSION}`
21
21
  export const HTTPS_SCHEMA = DEFAULT_CONFIG.HTTPS_SCHEMA
22
22
  export const DB_NAME = database_name
23
+
24
+ // TODO spostare nell'oggetto providers anche le altre configurazioni
23
25
  export const AUTH_CONFIG = {
24
26
  authCollection: auth_collection,
25
27
  userCollection: collection_name,
26
28
  resetPasswordCollection: 'reset-password-requests',
27
- resetPasswordConfig: configuration['local-userpass'].config,
29
+ resetPasswordConfig: configuration['local-userpass']?.config,
28
30
  user_id_field,
29
- on_user_creation_function_name
31
+ on_user_creation_function_name,
32
+ providers: {
33
+ "custom-function": configuration['custom-function']?.config
34
+ }
30
35
  }
36
+
37
+
38
+
39
+ export const S3_CONFIG = {
40
+ ACCESS_KEY_ID: process.env.S3_ACCESS_KEY_ID,
41
+ SECRET_ACCESS_KEY: process.env.S3_SECRET_ACCESS_KEY
42
+ }
@@ -66,22 +66,42 @@ export const generateHandler = ({
66
66
  rulesList
67
67
  }: GenerateHandlerParams) => {
68
68
  return async (req: FastifyRequest, res: FastifyReply) => {
69
- try {
69
+ const { body: originalBody, headers, query } = req
70
+
71
+ const customBody = {
72
+ text: () => JSON.stringify(originalBody)
73
+ }
70
74
 
71
- // TODO gestire tramite http_method le args da passare
75
+ const customResponseBody: {
76
+ data: unknown
77
+ } = {
78
+ data: null
79
+ }
80
+ try {
81
+ const customResponse = {
82
+ setStatusCode: (code: number) => {
83
+ res.status(code)
84
+ },
85
+ setBody: (body: unknown) => {
86
+ customResponseBody.data = body
87
+ }
88
+ }
72
89
 
73
90
  const response = await GenerateContext({
74
- args: [], // TODO passare solo body e query ???
91
+ args: [
92
+ { body: customBody, headers, query: JSON.parse(JSON.stringify(query)) },
93
+ customResponse
94
+ ],
75
95
  app,
76
96
  rules: rulesList,
77
97
  user: req.user,
78
98
  currentFunction,
79
99
  functionsList,
80
- services
100
+ services,
101
+ deserializeArgs: false
81
102
  })
82
103
 
83
- return res.send(response)
84
-
104
+ return res.send(customResponseBody.data ?? response)
85
105
  } catch (e) {
86
106
  console.log(e)
87
107
  }
@@ -0,0 +1,48 @@
1
+
2
+ // TODO gestire session di esecuzione in base all'utente
3
+ export class FunctionsQueue {
4
+ private q: Array<() => Promise<void>> = [];
5
+ private running = false;
6
+
7
+ add<T>(task: () => Promise<T>, enqueue: boolean = false): Promise<T> {
8
+ if (!enqueue) {
9
+ return (async () => {
10
+ return await task()
11
+ // try {
12
+ // this.running = true;
13
+ // const res = await task();
14
+ // this.running = false;
15
+ // return res
16
+ // }
17
+ // catch (e) {
18
+ // this.running = false
19
+ // throw e;
20
+ // }
21
+
22
+ })();
23
+ }
24
+
25
+ return new Promise<T>((resolve, reject) => {
26
+ this.q.push(async () => {
27
+ try { resolve(await task()); }
28
+ catch (e) { reject(e as unknown); }
29
+ });
30
+ void this.run();
31
+ });
32
+ }
33
+
34
+ private async run(): Promise<void> {
35
+ if (this.running) return;
36
+ this.running = true;
37
+ try {
38
+ while (this.q.length) {
39
+ const t = this.q.shift()!;
40
+ try { await t(); } catch (e) {
41
+ console.log(e)
42
+ }
43
+ }
44
+ } finally {
45
+ this.running = false;
46
+ }
47
+ }
48
+ }