@flowerforce/flowerbase 1.0.3-beta.6 → 1.0.3-beta.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/auth/providers/custom-function/controller.d.ts.map +1 -1
- package/dist/auth/providers/custom-function/controller.js +13 -8
- package/dist/auth/providers/local-userpass/controller.js +2 -1
- package/dist/auth/utils.d.ts +1 -1
- package/dist/auth/utils.d.ts.map +1 -1
- package/dist/auth/utils.js +8 -2
- package/dist/services/mongodb-atlas/index.d.ts.map +1 -1
- package/dist/services/mongodb-atlas/index.js +0 -15
- package/dist/shared/handleUserRegistration.d.ts.map +1 -1
- package/dist/shared/handleUserRegistration.js +5 -6
- package/dist/shared/models/handleUserRegistration.model.d.ts +6 -0
- package/dist/shared/models/handleUserRegistration.model.d.ts.map +1 -1
- package/dist/shared/models/handleUserRegistration.model.js +6 -0
- package/dist/utils/initializer/exposeRoutes.d.ts.map +1 -1
- package/dist/utils/initializer/exposeRoutes.js +2 -1
- package/package.json +1 -1
- package/src/auth/providers/custom-function/controller.ts +13 -8
- package/src/auth/providers/local-userpass/controller.ts +2 -2
- package/src/auth/utils.ts +14 -3
- package/src/services/mongodb-atlas/index.ts +0 -18
- package/src/shared/handleUserRegistration.ts +6 -7
- package/src/shared/models/handleUserRegistration.model.ts +8 -1
- package/src/utils/initializer/exposeRoutes.ts +3 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/custom-function/controller.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/custom-function/controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAezC;;;;GAIG;AACH,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,eAAe,iBA8ElE"}
|
|
@@ -8,10 +8,14 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
11
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
15
|
exports.customFunctionController = customFunctionController;
|
|
13
|
-
const bson_1 = require("bson");
|
|
14
16
|
const constants_1 = require("../../../constants");
|
|
17
|
+
const handleUserRegistration_1 = __importDefault(require("../../../shared/handleUserRegistration"));
|
|
18
|
+
const handleUserRegistration_model_1 = require("../../../shared/models/handleUserRegistration.model");
|
|
15
19
|
const state_1 = require("../../../state");
|
|
16
20
|
const context_1 = require("../../../utils/context");
|
|
17
21
|
const utils_1 = require("../../utils");
|
|
@@ -62,18 +66,19 @@ function customFunctionController(app) {
|
|
|
62
66
|
id
|
|
63
67
|
}
|
|
64
68
|
});
|
|
65
|
-
const currentUserData = {
|
|
66
|
-
_id: new bson_1.ObjectId(res.id),
|
|
67
|
-
user_data: {
|
|
68
|
-
_id: new bson_1.ObjectId(res.id),
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
69
|
if (res.id) {
|
|
70
|
+
const user = yield (0, handleUserRegistration_1.default)(app, { run_as_system: true, skipUserCheck: true, provider: handleUserRegistration_model_1.PROVIDER.CUSTOM_FUNCTION })({ email: res.id, password: (0, utils_1.generatePassword)() });
|
|
71
|
+
const currentUserData = {
|
|
72
|
+
_id: user.insertedId,
|
|
73
|
+
user_data: {
|
|
74
|
+
_id: user.insertedId,
|
|
75
|
+
}
|
|
76
|
+
};
|
|
72
77
|
return {
|
|
73
78
|
access_token: this.createAccessToken(currentUserData),
|
|
74
79
|
refresh_token: this.createRefreshToken(currentUserData),
|
|
75
80
|
device_id: '',
|
|
76
|
-
user_id:
|
|
81
|
+
user_id: user.insertedId.toString(),
|
|
77
82
|
};
|
|
78
83
|
}
|
|
79
84
|
throw new Error("Authentication Failed");
|
|
@@ -17,6 +17,7 @@ const mail_1 = __importDefault(require("@sendgrid/mail"));
|
|
|
17
17
|
const constants_1 = require("../../../constants");
|
|
18
18
|
const services_1 = require("../../../services");
|
|
19
19
|
const handleUserRegistration_1 = __importDefault(require("../../../shared/handleUserRegistration"));
|
|
20
|
+
const handleUserRegistration_model_1 = require("../../../shared/models/handleUserRegistration.model");
|
|
20
21
|
const state_1 = require("../../../state");
|
|
21
22
|
const context_1 = require("../../../utils/context");
|
|
22
23
|
const crypto_1 = require("../../../utils/crypto");
|
|
@@ -42,7 +43,7 @@ function localUserPassController(app) {
|
|
|
42
43
|
app.post(utils_1.AUTH_ENDPOINTS.REGISTRATION, {
|
|
43
44
|
schema: utils_1.REGISTRATION_SCHEMA
|
|
44
45
|
}, (req, res) => __awaiter(this, void 0, void 0, function* () {
|
|
45
|
-
const result = yield (0, handleUserRegistration_1.default)(app, { run_as_system: true })({ email: req.body.email.toLowerCase(), password: req.body.password });
|
|
46
|
+
const result = yield (0, handleUserRegistration_1.default)(app, { run_as_system: true, provider: handleUserRegistration_model_1.PROVIDER.LOCAL_USERPASS })({ email: req.body.email.toLowerCase(), password: req.body.password });
|
|
46
47
|
res === null || res === void 0 ? void 0 : res.status(201);
|
|
47
48
|
return { userId: result === null || result === void 0 ? void 0 : result.insertedId.toString() };
|
|
48
49
|
}));
|
package/dist/auth/utils.d.ts
CHANGED
|
@@ -116,7 +116,6 @@ export interface CustomUserDataConfig {
|
|
|
116
116
|
user_id_field: string;
|
|
117
117
|
on_user_creation_function_name: string;
|
|
118
118
|
}
|
|
119
|
-
export declare const PROVIDER_TYPE = "local-userpass";
|
|
120
119
|
/**
|
|
121
120
|
* > Loads the auth config json file
|
|
122
121
|
* @testable
|
|
@@ -133,5 +132,6 @@ export declare const getMailConfig: (resetPasswordConfig: Config, token: string,
|
|
|
133
132
|
mailToken: string;
|
|
134
133
|
body: string;
|
|
135
134
|
};
|
|
135
|
+
export declare const generatePassword: (length?: number) => string;
|
|
136
136
|
export {};
|
|
137
137
|
//# sourceMappingURL=utils.d.ts.map
|
package/dist/auth/utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/auth/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/auth/utils.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,YAAY;;;;;;;;;;;;;CASxB,CAAA;AAED,eAAO,MAAM,YAAY;;;;;;;;;;;;;CASxB,CAAA;AAED,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;CAUhC,CAAA;AAED,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;CAS/B,CAAA;AAED,oBAAY,cAAc;IACxB,KAAK,WAAW;IAChB,YAAY,cAAc;IAC1B,OAAO,aAAa;IACpB,OAAO,aAAa;IACpB,KAAK,gBAAgB;IACrB,aAAa,WAAW;IACxB,UAAU,sBAAsB;CACjC;AAED,oBAAY,WAAW;IACrB,mBAAmB,wBAAwB;IAC3C,aAAa,mCAAmC;IAChD,oBAAoB,sCAAsC;CAC3D;AAED,MAAM,WAAW,UAAU;IACzB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,gBAAgB,EAAE,aAAa,CAAA;IAC/B,iBAAiB,EAAE,cAAc,CAAA;CAClC;AAED,UAAU,MAAM;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;CAClB;AACD,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,UAAU,cAAc;IACtB,IAAI,EAAE,iBAAiB,CAAC;IACxB,IAAI,EAAE,iBAAiB,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE;QACN,kBAAkB,EAAE,MAAM,CAAA;KAC3B,CAAA;CACF;AAED,MAAM,WAAW,MAAM;IACrB,WAAW,EAAE,OAAO,CAAA;IACpB,iBAAiB,EAAE,MAAM,CAAA;IACzB,gBAAgB,EAAE,MAAM,CAAA;IACxB,uBAAuB,EAAE,OAAO,CAAA;IAChC,gBAAgB,EAAE,OAAO,CAAA;IACzB,UAAU,EAAE;QACV,IAAI,EAAE,MAAM,CAAA;QACZ,OAAO,EAAE,MAAM,CAAA;QACf,SAAS,EAAE,MAAM,CAAA;KAClB,CAAA;CACF;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAA;IAChB,kBAAkB,EAAE,MAAM,CAAA;IAC1B,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;IACrB,8BAA8B,EAAE,MAAM,CAAA;CACvC;AAGD;;;GAGG;AACH,eAAO,MAAM,cAAc,QAAO,UAGjC,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAAO,oBAGrC,CAAA;AAED,eAAO,MAAM,aAAa,GACxB,qBAAqB,MAAM,EAC3B,OAAO,MAAM,EACb,SAAS,MAAM;;;;;CA2DhB,CAAA;AAMD,eAAO,MAAM,gBAAgB,GAAI,eAAW,WAG3C,CAAA"}
|
package/dist/auth/utils.js
CHANGED
|
@@ -3,9 +3,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.generatePassword = exports.getMailConfig = exports.loadCustomUserData = exports.loadAuthConfig = exports.AUTH_ERRORS = exports.AUTH_ENDPOINTS = exports.REGISTRATION_SCHEMA = exports.CONFIRM_RESET_SCHEMA = exports.RESET_SCHEMA = exports.LOGIN_SCHEMA = void 0;
|
|
7
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
7
8
|
const fs_1 = __importDefault(require("fs"));
|
|
8
9
|
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const CHARSET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]{};:,.<>?";
|
|
9
11
|
exports.LOGIN_SCHEMA = {
|
|
10
12
|
body: {
|
|
11
13
|
type: 'object',
|
|
@@ -63,7 +65,6 @@ var AUTH_ERRORS;
|
|
|
63
65
|
AUTH_ERRORS["INVALID_TOKEN"] = "Invalid refresh token provided";
|
|
64
66
|
AUTH_ERRORS["INVALID_RESET_PARAMS"] = "Invalid token or tokenId provided";
|
|
65
67
|
})(AUTH_ERRORS || (exports.AUTH_ERRORS = AUTH_ERRORS = {}));
|
|
66
|
-
exports.PROVIDER_TYPE = 'local-userpass';
|
|
67
68
|
/**
|
|
68
69
|
* > Loads the auth config json file
|
|
69
70
|
* @testable
|
|
@@ -133,3 +134,8 @@ const getMailConfig = (resetPasswordConfig, token, tokenId) => {
|
|
|
133
134
|
};
|
|
134
135
|
};
|
|
135
136
|
exports.getMailConfig = getMailConfig;
|
|
137
|
+
const generatePassword = (length = 20) => {
|
|
138
|
+
const bytes = crypto_1.default.randomBytes(length);
|
|
139
|
+
return Array.from(bytes, (b) => CHARSET[b % CHARSET.length]).join("");
|
|
140
|
+
};
|
|
141
|
+
exports.generatePassword = generatePassword;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/mongodb-atlas/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAyC,oBAAoB,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/mongodb-atlas/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAyC,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAkpBrF,QAAA,MAAM,YAAY,EAAE,oBAmBlB,CAAA;AAEF,eAAe,YAAY,CAAA"}
|
|
@@ -161,11 +161,7 @@ const getOperators = (collection, { rules = {}, collName, user, run_as_system })
|
|
|
161
161
|
* - If validation fails, throws an error; otherwise, updates the document.
|
|
162
162
|
*/
|
|
163
163
|
updateOne: (query, data, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
164
|
-
console.log('Step1 - query', query);
|
|
165
|
-
console.log('Step1 - data', data);
|
|
166
|
-
console.log('Step1 - options', options);
|
|
167
164
|
if (!run_as_system) {
|
|
168
|
-
console.log('Step1 - runs_as_system');
|
|
169
165
|
(0, utils_2.checkDenyOperation)(rules, collection.collectionName, model_1.CRUD_OPERATIONS.UPDATE);
|
|
170
166
|
const { filters, roles } = rules[collName] || {};
|
|
171
167
|
// Apply access control filters
|
|
@@ -175,18 +171,10 @@ const getOperators = (collection, { rules = {}, collName, user, run_as_system })
|
|
|
175
171
|
? (0, utils_2.normalizeQuery)(formattedQuery)
|
|
176
172
|
: formattedQuery;
|
|
177
173
|
const result = yield collection.findOne({ $and: safeQuery });
|
|
178
|
-
/* const formattedQuery = getFormattedQuery(filters, query, user) */
|
|
179
|
-
console.log('Step2 - formattedQuery', formattedQuery);
|
|
180
|
-
// Retrieve the document to check permissions before updating
|
|
181
|
-
console.log('Step2 after fq - collection ', collection);
|
|
182
|
-
/* const result = await collection.findOne({ $and: formattedQuery }) */
|
|
183
|
-
console.log('result ', result);
|
|
184
174
|
if (!result) {
|
|
185
|
-
console.log('check step error in !result');
|
|
186
175
|
throw new Error('Update not permitted');
|
|
187
176
|
}
|
|
188
177
|
const winningRole = (0, utils_1.getWinningRole)(result, user, roles);
|
|
189
|
-
console.log('Step3 - winningRole', winningRole);
|
|
190
178
|
// Check if the update data contains MongoDB update operators (e.g., $set, $inc)
|
|
191
179
|
const hasOperators = Object.keys(data).some((key) => key.startsWith('$'));
|
|
192
180
|
// Flatten the update object to extract the actual fields being modified
|
|
@@ -203,7 +191,6 @@ const getOperators = (collection, { rules = {}, collName, user, run_as_system })
|
|
|
203
191
|
},
|
|
204
192
|
...Object.entries(data).map(([key, value]) => ({ [key]: value }))
|
|
205
193
|
];
|
|
206
|
-
console.log('Step5 - pipeline', pipeline);
|
|
207
194
|
const [docToCheck] = hasOperators
|
|
208
195
|
? yield collection.aggregate(pipeline).toArray()
|
|
209
196
|
: [data];
|
|
@@ -216,11 +203,9 @@ const getOperators = (collection, { rules = {}, collName, user, run_as_system })
|
|
|
216
203
|
expansions: {}
|
|
217
204
|
}, user)
|
|
218
205
|
: { status: true, document: docToCheck };
|
|
219
|
-
console.log('Step6 - status', status);
|
|
220
206
|
// Ensure no unauthorized changes are made
|
|
221
207
|
const areDocumentsEqual = (0, isEqual_1.default)(document, docToCheck);
|
|
222
208
|
if (!status || !areDocumentsEqual) {
|
|
223
|
-
console.log('check step error in status or documentsEqual');
|
|
224
209
|
throw new Error('Update not permitted');
|
|
225
210
|
}
|
|
226
211
|
return collection.updateOne({ $and: formattedQuery }, data, options);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handleUserRegistration.d.ts","sourceRoot":"","sources":["../../src/shared/handleUserRegistration.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"handleUserRegistration.d.ts","sourceRoot":"","sources":["../../src/shared/handleUserRegistration.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAA;AAE9E;;;;;;GAMG;AACH,QAAA,MAAM,sBAAsB,EAAE,sBAkD7B,CAAA;AAED,eAAe,sBAAsB,CAAA"}
|
|
@@ -9,7 +9,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
const utils_1 = require("../auth/utils");
|
|
13
12
|
const constants_1 = require("../constants");
|
|
14
13
|
const crypto_1 = require("../utils/crypto");
|
|
15
14
|
/**
|
|
@@ -20,7 +19,7 @@ const crypto_1 = require("../utils/crypto");
|
|
|
20
19
|
* @returns {Promise<InsertOneResult<Document>>} A promise resolving to the result of the insert operation.
|
|
21
20
|
*/
|
|
22
21
|
const handleUserRegistration = (app, opt) => (_a) => __awaiter(void 0, [_a], void 0, function* ({ email, password }) {
|
|
23
|
-
const { run_as_system } = opt !== null && opt !== void 0 ? opt : {};
|
|
22
|
+
const { run_as_system, skipUserCheck, provider } = opt !== null && opt !== void 0 ? opt : {};
|
|
24
23
|
if (!run_as_system) {
|
|
25
24
|
throw new Error('only run_as_system');
|
|
26
25
|
}
|
|
@@ -29,19 +28,19 @@ const handleUserRegistration = (app, opt) => (_a) => __awaiter(void 0, [_a], voi
|
|
|
29
28
|
const db = mongo.client.db(constants_1.DB_NAME);
|
|
30
29
|
const hashedPassword = yield (0, crypto_1.hashPassword)(password);
|
|
31
30
|
const existingUser = yield (db === null || db === void 0 ? void 0 : db.collection(authCollection).findOne({ email }));
|
|
32
|
-
if (existingUser) {
|
|
31
|
+
if (existingUser && !skipUserCheck) {
|
|
33
32
|
throw new Error('This email address is already used');
|
|
34
33
|
}
|
|
35
34
|
const result = yield (db === null || db === void 0 ? void 0 : db.collection(authCollection).insertOne({
|
|
36
35
|
email,
|
|
37
36
|
password: hashedPassword,
|
|
38
|
-
status: 'pending',
|
|
37
|
+
status: skipUserCheck ? 'confirmed' : 'pending',
|
|
39
38
|
custom_data: {
|
|
40
39
|
// TODO: aggiungere dati personalizzati alla registrazione
|
|
41
40
|
},
|
|
42
41
|
identities: [
|
|
43
42
|
{
|
|
44
|
-
provider_type:
|
|
43
|
+
provider_type: provider,
|
|
45
44
|
provider_data: { email }
|
|
46
45
|
}
|
|
47
46
|
]
|
|
@@ -52,7 +51,7 @@ const handleUserRegistration = (app, opt) => (_a) => __awaiter(void 0, [_a], voi
|
|
|
52
51
|
{
|
|
53
52
|
id: result === null || result === void 0 ? void 0 : result.insertedId.toString(),
|
|
54
53
|
provider_id: result === null || result === void 0 ? void 0 : result.insertedId.toString(),
|
|
55
|
-
provider_type:
|
|
54
|
+
provider_type: provider,
|
|
56
55
|
provider_data: { email }
|
|
57
56
|
}
|
|
58
57
|
]
|
|
@@ -9,8 +9,14 @@ type RegistrationParams = {
|
|
|
9
9
|
export type Options = {
|
|
10
10
|
user?: User;
|
|
11
11
|
rules?: Rules;
|
|
12
|
+
skipUserCheck?: boolean;
|
|
13
|
+
provider?: PROVIDER;
|
|
12
14
|
run_as_system?: boolean;
|
|
13
15
|
};
|
|
14
16
|
export type HandleUserRegistration = (app: FastifyInstance, opt: Options) => (params: RegistrationParams) => Promise<InsertOneResult<Document>>;
|
|
17
|
+
export declare enum PROVIDER {
|
|
18
|
+
LOCAL_USERPASS = "local-userpass",
|
|
19
|
+
CUSTOM_FUNCTION = "custom-function"
|
|
20
|
+
}
|
|
15
21
|
export {};
|
|
16
22
|
//# sourceMappingURL=handleUserRegistration.model.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handleUserRegistration.model.d.ts","sourceRoot":"","sources":["../../../src/shared/models/handleUserRegistration.model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAA;AAEtD,KAAK,kBAAkB,GAAG;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB,CAAA;AAED,MAAM,MAAM,sBAAsB,GAAG,CACnC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,OAAO,KACT,CAAC,MAAM,EAAE,kBAAkB,KAAK,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"handleUserRegistration.model.d.ts","sourceRoot":"","sources":["../../../src/shared/models/handleUserRegistration.model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AACjD,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,gCAAgC,CAAA;AAEtD,KAAK,kBAAkB,GAAG;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB,CAAA;AAED,MAAM,MAAM,sBAAsB,GAAG,CACnC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,OAAO,KACT,CAAC,MAAM,EAAE,kBAAkB,KAAK,OAAO,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAA;AAEvE,oBAAY,QAAQ;IAClB,cAAc,mBAAmB;IACjC,eAAe,oBAAoB;CACpC"}
|
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PROVIDER = void 0;
|
|
4
|
+
var PROVIDER;
|
|
5
|
+
(function (PROVIDER) {
|
|
6
|
+
PROVIDER["LOCAL_USERPASS"] = "local-userpass";
|
|
7
|
+
PROVIDER["CUSTOM_FUNCTION"] = "custom-function";
|
|
8
|
+
})(PROVIDER || (exports.PROVIDER = PROVIDER = {}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exposeRoutes.d.ts","sourceRoot":"","sources":["../../../src/utils/initializer/exposeRoutes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"exposeRoutes.d.ts","sourceRoot":"","sources":["../../../src/utils/initializer/exposeRoutes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAOzC;;;;GAIG;AACH,eAAO,MAAM,YAAY,GAAU,SAAS,eAAe,kBAiE1D,CAAA"}
|
|
@@ -13,6 +13,7 @@ exports.exposeRoutes = void 0;
|
|
|
13
13
|
const node_process_1 = require("node:process");
|
|
14
14
|
const utils_1 = require("../../auth/utils");
|
|
15
15
|
const constants_1 = require("../../constants");
|
|
16
|
+
const handleUserRegistration_model_1 = require("../../shared/models/handleUserRegistration.model");
|
|
16
17
|
const crypto_1 = require("../crypto");
|
|
17
18
|
/**
|
|
18
19
|
* > Used to expose all app routes
|
|
@@ -64,7 +65,7 @@ const exposeRoutes = (fastify) => __awaiter(void 0, void 0, void 0, function* ()
|
|
|
64
65
|
{
|
|
65
66
|
id: result === null || result === void 0 ? void 0 : result.insertedId.toString(),
|
|
66
67
|
provider_id: result === null || result === void 0 ? void 0 : result.insertedId.toString(),
|
|
67
|
-
provider_type:
|
|
68
|
+
provider_type: handleUserRegistration_model_1.PROVIDER.LOCAL_USERPASS,
|
|
68
69
|
provider_data: { email }
|
|
69
70
|
}
|
|
70
71
|
]
|
package/package.json
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { ObjectId } from 'bson'
|
|
2
1
|
import { FastifyInstance } from 'fastify'
|
|
3
2
|
import { AUTH_CONFIG } from '../../../constants'
|
|
3
|
+
import handleUserRegistration from '../../../shared/handleUserRegistration'
|
|
4
|
+
import { PROVIDER } from '../../../shared/models/handleUserRegistration.model'
|
|
4
5
|
import { StateManager } from '../../../state'
|
|
5
6
|
import { GenerateContext } from '../../../utils/context'
|
|
6
7
|
import {
|
|
7
8
|
AUTH_ENDPOINTS,
|
|
9
|
+
generatePassword,
|
|
8
10
|
} from '../../utils'
|
|
9
11
|
import {
|
|
10
12
|
LoginDto
|
|
@@ -72,18 +74,21 @@ export async function customFunctionController(app: FastifyInstance) {
|
|
|
72
74
|
}
|
|
73
75
|
})
|
|
74
76
|
|
|
75
|
-
|
|
76
|
-
_id: new ObjectId(res.id),
|
|
77
|
-
user_data: {
|
|
78
|
-
_id: new ObjectId(res.id),
|
|
79
|
-
}
|
|
80
|
-
}
|
|
77
|
+
|
|
81
78
|
if (res.id) {
|
|
79
|
+
const user = await handleUserRegistration(app, { run_as_system: true, skipUserCheck: true, provider: PROVIDER.CUSTOM_FUNCTION })({ email: res.id, password: generatePassword() })
|
|
80
|
+
|
|
81
|
+
const currentUserData = {
|
|
82
|
+
_id: user.insertedId,
|
|
83
|
+
user_data: {
|
|
84
|
+
_id: user.insertedId,
|
|
85
|
+
}
|
|
86
|
+
}
|
|
82
87
|
return {
|
|
83
88
|
access_token: this.createAccessToken(currentUserData),
|
|
84
89
|
refresh_token: this.createRefreshToken(currentUserData),
|
|
85
90
|
device_id: '',
|
|
86
|
-
user_id:
|
|
91
|
+
user_id: user.insertedId.toString(),
|
|
87
92
|
}
|
|
88
93
|
}
|
|
89
94
|
|
|
@@ -3,6 +3,7 @@ import { FastifyInstance } from 'fastify'
|
|
|
3
3
|
import { AUTH_CONFIG, DB_NAME } from '../../../constants'
|
|
4
4
|
import { services } from '../../../services'
|
|
5
5
|
import handleUserRegistration from '../../../shared/handleUserRegistration'
|
|
6
|
+
import { PROVIDER } from '../../../shared/models/handleUserRegistration.model'
|
|
6
7
|
import { StateManager } from '../../../state'
|
|
7
8
|
import { GenerateContext } from '../../../utils/context'
|
|
8
9
|
import { comparePassword, generateToken, hashPassword } from '../../../utils/crypto'
|
|
@@ -21,7 +22,6 @@ import {
|
|
|
21
22
|
RegistrationDto,
|
|
22
23
|
ResetPasswordDto
|
|
23
24
|
} from './dtos'
|
|
24
|
-
|
|
25
25
|
/**
|
|
26
26
|
* Controller for handling local user registration and login.
|
|
27
27
|
* @testable
|
|
@@ -53,7 +53,7 @@ export async function localUserPassController(app: FastifyInstance) {
|
|
|
53
53
|
},
|
|
54
54
|
async (req, res) => {
|
|
55
55
|
|
|
56
|
-
const result = await handleUserRegistration(app, { run_as_system: true })({ email: req.body.email.toLowerCase(), password: req.body.password })
|
|
56
|
+
const result = await handleUserRegistration(app, { run_as_system: true, provider: PROVIDER.LOCAL_USERPASS })({ email: req.body.email.toLowerCase(), password: req.body.password })
|
|
57
57
|
|
|
58
58
|
res?.status(201)
|
|
59
59
|
return { userId: result?.insertedId.toString() }
|
package/src/auth/utils.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import crypto from "crypto";
|
|
1
2
|
import fs from 'fs'
|
|
2
3
|
import path from 'path'
|
|
3
4
|
|
|
5
|
+
const CHARSET =
|
|
6
|
+
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_=+[]{};:,.<>?";
|
|
4
7
|
export const LOGIN_SCHEMA = {
|
|
5
8
|
body: {
|
|
6
9
|
type: 'object',
|
|
@@ -112,7 +115,6 @@ export interface CustomUserDataConfig {
|
|
|
112
115
|
on_user_creation_function_name: string
|
|
113
116
|
}
|
|
114
117
|
|
|
115
|
-
export const PROVIDER_TYPE = 'local-userpass'
|
|
116
118
|
|
|
117
119
|
/**
|
|
118
120
|
* > Loads the auth config json file
|
|
@@ -152,7 +154,7 @@ export const getMailConfig = (
|
|
|
152
154
|
|
|
153
155
|
if (!subjectPath) {
|
|
154
156
|
throw new Error(`Invalid subjectPath: ${subjectPath}`)
|
|
155
|
-
}
|
|
157
|
+
}
|
|
156
158
|
|
|
157
159
|
const currentSubject =
|
|
158
160
|
(subjectPrefix === ENV_PREFIX ? process.env[subjectPath] : subject) ?? ''
|
|
@@ -160,7 +162,7 @@ export const getMailConfig = (
|
|
|
160
162
|
|
|
161
163
|
if (!mailTokenPath) {
|
|
162
164
|
throw new Error(`Invalid mailTokenPath: ${mailTokenPath}`)
|
|
163
|
-
}
|
|
165
|
+
}
|
|
164
166
|
|
|
165
167
|
const currentMailToken =
|
|
166
168
|
(mailTokenPrefix === 'ENV' ? process.env[mailTokenPath] : mailToken) ?? ''
|
|
@@ -195,3 +197,12 @@ export const getMailConfig = (
|
|
|
195
197
|
body
|
|
196
198
|
}
|
|
197
199
|
}
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
export const generatePassword = (length = 20) => {
|
|
206
|
+
const bytes = crypto.randomBytes(length);
|
|
207
|
+
return Array.from(bytes, (b) => CHARSET[b % CHARSET.length]).join("");
|
|
208
|
+
}
|
|
@@ -183,11 +183,7 @@ const getOperators: GetOperatorsFunction = (
|
|
|
183
183
|
* - If validation fails, throws an error; otherwise, updates the document.
|
|
184
184
|
*/
|
|
185
185
|
updateOne: async (query, data, options) => {
|
|
186
|
-
console.log('Step1 - query', query)
|
|
187
|
-
console.log('Step1 - data', data)
|
|
188
|
-
console.log('Step1 - options', options)
|
|
189
186
|
if (!run_as_system) {
|
|
190
|
-
console.log('Step1 - runs_as_system')
|
|
191
187
|
|
|
192
188
|
checkDenyOperation(rules, collection.collectionName, CRUD_OPERATIONS.UPDATE)
|
|
193
189
|
const { filters, roles } = rules[collName] || {}
|
|
@@ -201,22 +197,11 @@ const getOperators: GetOperatorsFunction = (
|
|
|
201
197
|
|
|
202
198
|
const result = await collection.findOne({ $and: safeQuery })
|
|
203
199
|
|
|
204
|
-
/* const formattedQuery = getFormattedQuery(filters, query, user) */
|
|
205
|
-
console.log('Step2 - formattedQuery', formattedQuery)
|
|
206
|
-
|
|
207
|
-
// Retrieve the document to check permissions before updating
|
|
208
|
-
console.log('Step2 after fq - collection ', collection)
|
|
209
|
-
/* const result = await collection.findOne({ $and: formattedQuery }) */
|
|
210
|
-
console.log('result ', result)
|
|
211
|
-
|
|
212
200
|
if (!result) {
|
|
213
|
-
console.log('check step error in !result')
|
|
214
|
-
|
|
215
201
|
throw new Error('Update not permitted')
|
|
216
202
|
}
|
|
217
203
|
|
|
218
204
|
const winningRole = getWinningRole(result, user, roles)
|
|
219
|
-
console.log('Step3 - winningRole', winningRole)
|
|
220
205
|
|
|
221
206
|
// Check if the update data contains MongoDB update operators (e.g., $set, $inc)
|
|
222
207
|
const hasOperators = Object.keys(data).some((key) => key.startsWith('$'))
|
|
@@ -235,7 +220,6 @@ const getOperators: GetOperatorsFunction = (
|
|
|
235
220
|
},
|
|
236
221
|
...Object.entries(data).map(([key, value]) => ({ [key]: value }))
|
|
237
222
|
]
|
|
238
|
-
console.log('Step5 - pipeline', pipeline)
|
|
239
223
|
const [docToCheck] = hasOperators
|
|
240
224
|
? await collection.aggregate(pipeline).toArray()
|
|
241
225
|
: ([data] as [Document])
|
|
@@ -252,12 +236,10 @@ const getOperators: GetOperatorsFunction = (
|
|
|
252
236
|
user
|
|
253
237
|
)
|
|
254
238
|
: { status: true, document: docToCheck }
|
|
255
|
-
console.log('Step6 - status', status)
|
|
256
239
|
// Ensure no unauthorized changes are made
|
|
257
240
|
const areDocumentsEqual = isEqual(document, docToCheck)
|
|
258
241
|
|
|
259
242
|
if (!status || !areDocumentsEqual) {
|
|
260
|
-
console.log('check step error in status or documentsEqual')
|
|
261
243
|
throw new Error('Update not permitted')
|
|
262
244
|
}
|
|
263
245
|
return collection.updateOne({ $and: formattedQuery }, data, options)
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { FastifyMongoObject } from "@fastify/mongodb/types"
|
|
2
|
-
import { PROVIDER_TYPE } from "../auth/utils"
|
|
3
2
|
import { AUTH_CONFIG, DB_NAME } from "../constants"
|
|
4
3
|
import { hashPassword } from "../utils/crypto"
|
|
5
4
|
import { HandleUserRegistration } from "./models/handleUserRegistration.model"
|
|
@@ -12,8 +11,8 @@ import { HandleUserRegistration } from "./models/handleUserRegistration.model"
|
|
|
12
11
|
* @returns {Promise<InsertOneResult<Document>>} A promise resolving to the result of the insert operation.
|
|
13
12
|
*/
|
|
14
13
|
const handleUserRegistration: HandleUserRegistration = (app, opt) => async ({ email, password }) => {
|
|
15
|
-
const { run_as_system } = opt ?? {}
|
|
16
|
-
|
|
14
|
+
const { run_as_system, skipUserCheck, provider } = opt ?? {}
|
|
15
|
+
|
|
17
16
|
if (!run_as_system) {
|
|
18
17
|
throw new Error('only run_as_system')
|
|
19
18
|
}
|
|
@@ -24,20 +23,20 @@ const handleUserRegistration: HandleUserRegistration = (app, opt) => async ({ em
|
|
|
24
23
|
const hashedPassword = await hashPassword(password)
|
|
25
24
|
|
|
26
25
|
const existingUser = await db?.collection(authCollection!).findOne({ email })
|
|
27
|
-
if (existingUser) {
|
|
26
|
+
if (existingUser && !skipUserCheck) {
|
|
28
27
|
throw new Error('This email address is already used')
|
|
29
28
|
}
|
|
30
29
|
|
|
31
30
|
const result = await db?.collection(authCollection!).insertOne({
|
|
32
31
|
email,
|
|
33
32
|
password: hashedPassword,
|
|
34
|
-
status: 'pending',
|
|
33
|
+
status: skipUserCheck ? 'confirmed' : 'pending',
|
|
35
34
|
custom_data: {
|
|
36
35
|
// TODO: aggiungere dati personalizzati alla registrazione
|
|
37
36
|
},
|
|
38
37
|
identities: [
|
|
39
38
|
{
|
|
40
|
-
provider_type:
|
|
39
|
+
provider_type: provider,
|
|
41
40
|
provider_data: { email }
|
|
42
41
|
}
|
|
43
42
|
]
|
|
@@ -51,7 +50,7 @@ const handleUserRegistration: HandleUserRegistration = (app, opt) => async ({ em
|
|
|
51
50
|
{
|
|
52
51
|
id: result?.insertedId.toString(),
|
|
53
52
|
provider_id: result?.insertedId.toString(),
|
|
54
|
-
provider_type:
|
|
53
|
+
provider_type: provider,
|
|
55
54
|
provider_data: { email }
|
|
56
55
|
}
|
|
57
56
|
]
|
|
@@ -11,10 +11,17 @@ type RegistrationParams = {
|
|
|
11
11
|
export type Options = {
|
|
12
12
|
user?: User
|
|
13
13
|
rules?: Rules
|
|
14
|
+
skipUserCheck?: boolean
|
|
15
|
+
provider?: PROVIDER
|
|
14
16
|
run_as_system?: boolean
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
export type HandleUserRegistration = (
|
|
18
20
|
app: FastifyInstance,
|
|
19
21
|
opt: Options
|
|
20
|
-
) => (params: RegistrationParams) => Promise<InsertOneResult<Document>>
|
|
22
|
+
) => (params: RegistrationParams) => Promise<InsertOneResult<Document>>
|
|
23
|
+
|
|
24
|
+
export enum PROVIDER {
|
|
25
|
+
LOCAL_USERPASS = "local-userpass",
|
|
26
|
+
CUSTOM_FUNCTION = "custom-function"
|
|
27
|
+
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { uptime } from 'node:process'
|
|
2
2
|
import { FastifyInstance } from 'fastify'
|
|
3
3
|
import { RegistrationDto } from '../../auth/providers/local-userpass/dtos'
|
|
4
|
-
import { AUTH_ENDPOINTS,
|
|
4
|
+
import { AUTH_ENDPOINTS, REGISTRATION_SCHEMA } from '../../auth/utils'
|
|
5
5
|
import { API_VERSION, AUTH_CONFIG, DB_NAME, DEFAULT_CONFIG } from '../../constants'
|
|
6
|
+
import { PROVIDER } from '../../shared/models/handleUserRegistration.model'
|
|
6
7
|
import { hashPassword } from '../crypto'
|
|
7
8
|
|
|
8
9
|
/**
|
|
@@ -59,7 +60,7 @@ export const exposeRoutes = async (fastify: FastifyInstance) => {
|
|
|
59
60
|
{
|
|
60
61
|
id: result?.insertedId.toString(),
|
|
61
62
|
provider_id: result?.insertedId.toString(),
|
|
62
|
-
provider_type:
|
|
63
|
+
provider_type: PROVIDER.LOCAL_USERPASS,
|
|
63
64
|
provider_data: { email }
|
|
64
65
|
}
|
|
65
66
|
]
|