@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.
- package/dist/auth/plugins/jwt.d.ts.map +1 -1
- package/dist/auth/plugins/jwt.js +2 -1
- package/dist/auth/providers/custom-function/controller.d.ts +8 -0
- package/dist/auth/providers/custom-function/controller.d.ts.map +1 -0
- package/dist/auth/providers/custom-function/controller.js +83 -0
- package/dist/auth/providers/custom-function/dtos.d.ts +15 -0
- package/dist/auth/providers/custom-function/dtos.d.ts.map +1 -0
- package/dist/auth/providers/custom-function/dtos.js +2 -0
- package/dist/auth/providers/custom-function/schema.d.ts +31 -0
- package/dist/auth/providers/custom-function/schema.d.ts.map +1 -0
- package/dist/auth/providers/custom-function/schema.js +25 -0
- package/dist/auth/providers/local-userpass/controller.d.ts.map +1 -1
- package/dist/auth/providers/local-userpass/controller.js +31 -59
- package/dist/auth/utils.d.ts +9 -0
- package/dist/auth/utils.d.ts.map +1 -1
- package/dist/constants.d.ts +9 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +13 -4
- package/dist/features/endpoints/utils.d.ts.map +1 -1
- package/dist/features/endpoints/utils.js +23 -4
- package/dist/features/functions/queue.d.ts +7 -0
- package/dist/features/functions/queue.d.ts.map +1 -0
- package/dist/features/functions/queue.js +69 -0
- package/dist/features/triggers/utils.d.ts.map +1 -1
- package/dist/features/triggers/utils.js +22 -6
- package/dist/services/auth/index.d.ts +4 -0
- package/dist/services/auth/index.d.ts.map +1 -0
- package/dist/services/auth/index.js +14 -0
- package/dist/services/auth/model.d.ts +12 -0
- package/dist/services/auth/model.d.ts.map +1 -0
- package/dist/services/auth/model.js +2 -0
- package/dist/services/aws/index.d.ts.map +1 -1
- package/dist/services/aws/index.js +7 -10
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +2 -0
- package/dist/services/mongodb-atlas/index.d.ts.map +1 -1
- package/dist/services/mongodb-atlas/index.js +28 -5
- package/dist/services/mongodb-atlas/utils.d.ts +17 -1
- package/dist/services/mongodb-atlas/utils.d.ts.map +1 -1
- package/dist/services/mongodb-atlas/utils.js +24 -11
- package/dist/shared/handleUserRegistration.d.ts +11 -0
- package/dist/shared/handleUserRegistration.d.ts.map +1 -0
- package/dist/shared/handleUserRegistration.js +62 -0
- package/dist/shared/models/handleUserRegistration.model.d.ts +16 -0
- package/dist/shared/models/handleUserRegistration.model.d.ts.map +1 -0
- package/dist/shared/models/handleUserRegistration.model.js +2 -0
- package/dist/state.d.ts.map +1 -1
- package/dist/state.js +3 -1
- package/dist/utils/context/helpers.d.ts +15 -1
- package/dist/utils/context/helpers.d.ts.map +1 -1
- package/dist/utils/context/helpers.js +2 -1
- package/dist/utils/context/index.d.ts +1 -1
- package/dist/utils/context/index.d.ts.map +1 -1
- package/dist/utils/context/index.js +31 -22
- package/dist/utils/context/interface.d.ts +6 -1
- package/dist/utils/context/interface.d.ts.map +1 -1
- package/dist/utils/initializer/registerPlugins.d.ts.map +1 -1
- package/dist/utils/initializer/registerPlugins.js +11 -3
- package/dist/utils/roles/helpers.js +1 -1
- package/package.json +1 -1
- package/src/auth/plugins/jwt.ts +4 -2
- package/src/auth/providers/custom-function/controller.ts +94 -0
- package/src/auth/providers/custom-function/dtos.ts +16 -0
- package/src/auth/providers/custom-function/schema.ts +25 -0
- package/src/auth/providers/local-userpass/controller.ts +45 -71
- package/src/auth/utils.ts +10 -0
- package/src/constants.ts +14 -2
- package/src/features/endpoints/utils.ts +26 -6
- package/src/features/functions/queue.ts +48 -0
- package/src/features/triggers/utils.ts +11 -6
- package/src/services/auth/index.ts +12 -0
- package/src/services/auth/model.ts +13 -0
- package/src/services/aws/index.ts +10 -11
- package/src/services/index.ts +2 -0
- package/src/services/mongodb-atlas/index.ts +61 -26
- package/src/services/mongodb-atlas/utils.ts +98 -59
- package/src/shared/handleUserRegistration.ts +64 -0
- package/src/shared/models/handleUserRegistration.model.ts +20 -0
- package/src/state.ts +4 -1
- package/src/utils/context/helpers.ts +6 -1
- package/src/utils/context/index.ts +46 -29
- package/src/utils/context/interface.ts +5 -1
- package/src/utils/initializer/registerPlugins.ts +9 -1
- 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
|
-
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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
|
-
|
|
46
|
-
|
|
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;
|
|
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;
|
|
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/
|
|
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
|
|
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:
|
|
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
package/src/auth/plugins/jwt.ts
CHANGED
|
@@ -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:
|
|
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 {
|
|
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
|
|
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
|
-
|
|
56
|
+
const result = await handleUserRegistration(app, { run_as_system: true })({ email: req.body.email.toLowerCase(), password: req.body.password })
|
|
93
57
|
|
|
94
|
-
|
|
95
|
-
|
|
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
|
|
76
|
+
const authUser = await db.collection(authCollection!).findOne({
|
|
114
77
|
email: req.body.username
|
|
115
78
|
})
|
|
116
79
|
|
|
117
|
-
if (!
|
|
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
|
-
|
|
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 =
|
|
131
|
-
|
|
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 = { ...
|
|
101
|
+
const userWithCustomData = { ...authUser, user_data: user, id: authUser._id.toString() }
|
|
135
102
|
|
|
136
|
-
if (
|
|
103
|
+
if (authUser && authUser.status === 'pending') {
|
|
137
104
|
try {
|
|
138
|
-
await db?.collection(authCollection!).updateOne(
|
|
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(
|
|
114
|
+
console.log('>>> 🚀 ~ localUserPassController ~ error:', error)
|
|
147
115
|
}
|
|
148
116
|
}
|
|
149
117
|
|
|
150
|
-
if (
|
|
151
|
-
|
|
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
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
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:
|
|
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(
|
|
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:
|
|
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
|
|
170
|
+
const authUser = await db.collection(authCollection!).findOne({
|
|
197
171
|
email
|
|
198
172
|
})
|
|
199
173
|
|
|
200
|
-
if (!
|
|
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']
|
|
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
|
-
|
|
69
|
+
const { body: originalBody, headers, query } = req
|
|
70
|
+
|
|
71
|
+
const customBody = {
|
|
72
|
+
text: () => JSON.stringify(originalBody)
|
|
73
|
+
}
|
|
70
74
|
|
|
71
|
-
|
|
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: [
|
|
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
|
+
}
|