@flowerforce/flowerbase 1.2.1-beta.10 → 1.2.1-beta.12

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.
@@ -1 +1 @@
1
- {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/local-userpass/controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAmCzC;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,eAAe,iBA+RjE"}
1
+ {"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/local-userpass/controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAqCzC;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,eAAe,iBAgUjE"}
@@ -109,6 +109,38 @@ function localUserPassController(app) {
109
109
  res === null || res === void 0 ? void 0 : res.status(201);
110
110
  return { userId: result.insertedId.toString() };
111
111
  }));
112
+ /**
113
+ * Endpoint for confirming a user registration.
114
+ *
115
+ * @route {POST} /confirm
116
+ * @param {ConfirmUserDto} req - The request object with confirmation data.
117
+ * @returns {Promise<Object>} A promise resolving with confirmation status.
118
+ */
119
+ app.post(utils_1.AUTH_ENDPOINTS.CONFIRM, {
120
+ schema: utils_1.CONFIRM_USER_SCHEMA
121
+ }, (req, res) => __awaiter(this, void 0, void 0, function* () {
122
+ const key = `confirm:${req.ip}`;
123
+ if (isRateLimited(key, resetMaxAttempts, rateLimitWindowMs)) {
124
+ res.status(429).send({ message: 'Too many requests' });
125
+ return;
126
+ }
127
+ const existing = yield db.collection(authCollection).findOne({
128
+ confirmationToken: req.body.token,
129
+ confirmationTokenId: req.body.tokenId
130
+ });
131
+ if (!existing) {
132
+ res.status(500);
133
+ throw new Error(utils_1.AUTH_ERRORS.INVALID_TOKEN);
134
+ }
135
+ if (existing.status !== 'confirmed') {
136
+ yield db.collection(authCollection).updateOne({ _id: existing._id }, {
137
+ $set: { status: 'confirmed' },
138
+ $unset: { confirmationToken: '', confirmationTokenId: '' }
139
+ });
140
+ }
141
+ res.status(200);
142
+ return { status: 'confirmed' };
143
+ }));
112
144
  /**
113
145
  * Endpoint for user login.
114
146
  *
@@ -142,17 +174,8 @@ function localUserPassController(app) {
142
174
  : {};
143
175
  authUser === null || authUser === void 0 ? true : delete authUser.password;
144
176
  const userWithCustomData = Object.assign(Object.assign({}, authUser), { user_data: Object.assign(Object.assign({}, (user || {})), { _id: authUser._id }), data: { email: authUser.email }, id: authUser._id.toString() });
145
- if (authUser && authUser.status === 'pending') {
146
- try {
147
- yield (db === null || db === void 0 ? void 0 : db.collection(authCollection).updateOne({ _id: authUser._id }, {
148
- $set: {
149
- status: 'confirmed'
150
- }
151
- }));
152
- }
153
- catch (error) {
154
- console.log('>>> 🚀 ~ localUserPassController ~ error:', error);
155
- }
177
+ if (authUser && authUser.status !== 'confirmed') {
178
+ throw new Error(utils_1.AUTH_ERRORS.USER_NOT_CONFIRMED);
156
179
  }
157
180
  const refreshToken = this.createRefreshToken(userWithCustomData);
158
181
  const refreshTokenHash = (0, crypto_1.hashToken)(refreshToken);
@@ -41,4 +41,10 @@ export interface ConfirmResetPasswordDto {
41
41
  password: string;
42
42
  };
43
43
  }
44
+ export interface ConfirmUserDto {
45
+ Body: {
46
+ token: string;
47
+ tokenId: string;
48
+ };
49
+ }
44
50
  //# sourceMappingURL=dtos.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dtos.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/local-userpass/dtos.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,eAAe,CAAA;CACtB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,YAAY,CAAA;IAClB,KAAK,EAAE,eAAe,GAAG,gBAAgB,CAAA;CAC1C;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAA;KACd,CAAA;CACF;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAA;QACb,QAAQ,EAAE,MAAM,CAAA;QAChB,SAAS,CAAC,EAAE,OAAO,EAAE,CAAA;KACtB,CAAA;CACF;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAA;QACb,OAAO,EAAE,MAAM,CAAA;QACf,QAAQ,EAAE,MAAM,CAAA;KACjB,CAAA;CACF"}
1
+ {"version":3,"file":"dtos.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/local-userpass/dtos.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,eAAe,CAAA;CACtB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,YAAY,CAAA;IAClB,KAAK,EAAE,eAAe,GAAG,gBAAgB,CAAA;CAC1C;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAA;KACd,CAAA;CACF;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAA;QACb,QAAQ,EAAE,MAAM,CAAA;QAChB,SAAS,CAAC,EAAE,OAAO,EAAE,CAAA;KACtB,CAAA;CACF;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAA;QACb,OAAO,EAAE,MAAM,CAAA;QACf,QAAQ,EAAE,MAAM,CAAA;KACjB,CAAA;CACF;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAA;QACb,OAAO,EAAE,MAAM,CAAA;KAChB,CAAA;CACF"}
@@ -72,6 +72,20 @@ export declare const CONFIRM_RESET_SCHEMA: {
72
72
  required: string[];
73
73
  };
74
74
  };
75
+ export declare const CONFIRM_USER_SCHEMA: {
76
+ body: {
77
+ type: string;
78
+ properties: {
79
+ token: {
80
+ type: string;
81
+ };
82
+ tokenId: {
83
+ type: string;
84
+ };
85
+ };
86
+ required: string[];
87
+ };
88
+ };
75
89
  export declare const RESET_SCHEMA: {
76
90
  body: {
77
91
  type: string;
@@ -108,6 +122,7 @@ export declare const REGISTRATION_SCHEMA: {
108
122
  export declare enum AUTH_ENDPOINTS {
109
123
  LOGIN = "/login",
110
124
  REGISTRATION = "/register",
125
+ CONFIRM = "/confirm",
111
126
  PROFILE = "/profile",
112
127
  SESSION = "/session",
113
128
  RESET = "/reset/send",
@@ -119,7 +134,8 @@ export declare enum AUTH_ERRORS {
119
134
  INVALID_CREDENTIALS = "Invalid credentials",
120
135
  INVALID_TOKEN = "Invalid refresh token provided",
121
136
  INVALID_RESET_PARAMS = "Invalid token or tokenId provided",
122
- MISSING_RESET_FUNCTION = "Missing reset function"
137
+ MISSING_RESET_FUNCTION = "Missing reset function",
138
+ USER_NOT_CONFIRMED = "User not confirmed"
123
139
  }
124
140
  export interface AuthConfig {
125
141
  auth_collection?: string;
@@ -148,6 +164,7 @@ interface CustomFunction {
148
164
  }
149
165
  export interface Config {
150
166
  autoConfirm: boolean;
167
+ confirmationFunctionName?: string;
151
168
  resetFunctionName: string;
152
169
  resetPasswordUrl: string;
153
170
  runConfirmationFunction: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/auth/utils.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;CAcxB,CAAA;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;CAa7B,CAAA;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;CAe7B,CAAA;AAED,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;CAUhC,CAAA;AAED,eAAO,MAAM,YAAY;;;;;;;;;;;;;CAAoB,CAAA;AAE7C,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;CAc/B,CAAA;AAED,oBAAY,cAAc;IACxB,KAAK,WAAW;IAChB,YAAY,cAAc;IAC1B,OAAO,aAAa;IACpB,OAAO,aAAa;IACpB,KAAK,gBAAgB;IACrB,UAAU,gBAAgB;IAC1B,aAAa,WAAW;IACxB,UAAU,sBAAsB;CACjC;AAED,oBAAY,WAAW;IACrB,mBAAmB,wBAAwB;IAC3C,aAAa,mCAAmC;IAChD,oBAAoB,sCAAsC;IAC1D,sBAAsB,2BAA2B;CAClD;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;CAC1B;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;AAMD;;;GAGG;AACH,eAAO,MAAM,cAAc,QAAO,UAGjC,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAAO,oBAGrC,CAAA;AAED,eAAO,MAAM,gBAAgB,GAAI,eAAW,WAG3C,CAAA"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/auth/utils.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;CAcxB,CAAA;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;CAa7B,CAAA;AAED,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;CAe7B,CAAA;AAED,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;CAUhC,CAAA;AAED,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;CAS/B,CAAA;AAED,eAAO,MAAM,YAAY;;;;;;;;;;;;;CAAoB,CAAA;AAE7C,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;CAc/B,CAAA;AAED,oBAAY,cAAc;IACxB,KAAK,WAAW;IAChB,YAAY,cAAc;IAC1B,OAAO,aAAa;IACpB,OAAO,aAAa;IACpB,OAAO,aAAa;IACpB,KAAK,gBAAgB;IACrB,UAAU,gBAAgB;IAC1B,aAAa,WAAW;IACxB,UAAU,sBAAsB;CACjC;AAED,oBAAY,WAAW;IACrB,mBAAmB,wBAAwB;IAC3C,aAAa,mCAAmC;IAChD,oBAAoB,sCAAsC;IAC1D,sBAAsB,2BAA2B;IACjD,kBAAkB,uBAAuB;CAC1C;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,wBAAwB,CAAC,EAAE,MAAM,CAAA;IACjC,iBAAiB,EAAE,MAAM,CAAA;IACzB,gBAAgB,EAAE,MAAM,CAAA;IACxB,uBAAuB,EAAE,OAAO,CAAA;IAChC,gBAAgB,EAAE,OAAO,CAAA;CAC1B;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;AAMD;;;GAGG;AACH,eAAO,MAAM,cAAc,QAAO,UAGjC,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,kBAAkB,QAAO,oBAGrC,CAAA;AAED,eAAO,MAAM,gBAAgB,GAAI,eAAW,WAG3C,CAAA"}
@@ -3,7 +3,7 @@ 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.generatePassword = exports.loadCustomUserData = exports.loadAuthConfig = exports.AUTH_ERRORS = exports.AUTH_ENDPOINTS = exports.REGISTRATION_SCHEMA = exports.RESET_SCHEMA = exports.CONFIRM_RESET_SCHEMA = exports.RESET_CALL_SCHEMA = exports.RESET_SEND_SCHEMA = exports.LOGIN_SCHEMA = void 0;
6
+ exports.generatePassword = exports.loadCustomUserData = exports.loadAuthConfig = exports.AUTH_ERRORS = exports.AUTH_ENDPOINTS = exports.REGISTRATION_SCHEMA = exports.RESET_SCHEMA = exports.CONFIRM_USER_SCHEMA = exports.CONFIRM_RESET_SCHEMA = exports.RESET_CALL_SCHEMA = exports.RESET_SEND_SCHEMA = exports.LOGIN_SCHEMA = void 0;
7
7
  const crypto_1 = __importDefault(require("crypto"));
8
8
  const fs_1 = __importDefault(require("fs"));
9
9
  const path_1 = __importDefault(require("path"));
@@ -64,6 +64,16 @@ exports.CONFIRM_RESET_SCHEMA = {
64
64
  required: ['password', 'token', 'tokenId']
65
65
  }
66
66
  };
67
+ exports.CONFIRM_USER_SCHEMA = {
68
+ body: {
69
+ type: 'object',
70
+ properties: {
71
+ token: { type: 'string' },
72
+ tokenId: { type: 'string' }
73
+ },
74
+ required: ['token', 'tokenId']
75
+ }
76
+ };
67
77
  exports.RESET_SCHEMA = exports.RESET_SEND_SCHEMA;
68
78
  exports.REGISTRATION_SCHEMA = {
69
79
  body: {
@@ -84,6 +94,7 @@ var AUTH_ENDPOINTS;
84
94
  (function (AUTH_ENDPOINTS) {
85
95
  AUTH_ENDPOINTS["LOGIN"] = "/login";
86
96
  AUTH_ENDPOINTS["REGISTRATION"] = "/register";
97
+ AUTH_ENDPOINTS["CONFIRM"] = "/confirm";
87
98
  AUTH_ENDPOINTS["PROFILE"] = "/profile";
88
99
  AUTH_ENDPOINTS["SESSION"] = "/session";
89
100
  AUTH_ENDPOINTS["RESET"] = "/reset/send";
@@ -97,6 +108,7 @@ var AUTH_ERRORS;
97
108
  AUTH_ERRORS["INVALID_TOKEN"] = "Invalid refresh token provided";
98
109
  AUTH_ERRORS["INVALID_RESET_PARAMS"] = "Invalid token or tokenId provided";
99
110
  AUTH_ERRORS["MISSING_RESET_FUNCTION"] = "Missing reset function";
111
+ AUTH_ERRORS["USER_NOT_CONFIRMED"] = "User not confirmed";
100
112
  })(AUTH_ERRORS || (exports.AUTH_ERRORS = AUTH_ERRORS = {}));
101
113
  const resolveAppPath = () => { var _a, _b, _c; return (_c = (_a = process.env.FLOWERBASE_APP_PATH) !== null && _a !== void 0 ? _a : (_b = require.main) === null || _b === void 0 ? void 0 : _b.path) !== null && _c !== void 0 ? _c : process.cwd(); };
102
114
  /**
@@ -28,6 +28,7 @@ export declare const AUTH_CONFIG: {
28
28
  resetPasswordCollection: string;
29
29
  refreshTokensCollection: string;
30
30
  resetPasswordConfig: import("./auth/utils").Config;
31
+ localUserpassConfig: import("./auth/utils").Config;
31
32
  user_id_field: string;
32
33
  on_user_creation_function_name: string;
33
34
  providers: {
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,IAAI,CAAA;AAUpC,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;iBAiBsB,eAAe,EAAE;;CAEjE,CAAA;AACD,eAAO,MAAM,WAAW,QAA8C,CAAA;AACtE,eAAO,MAAM,YAAY,QAA8B,CAAA;AACvD,eAAO,MAAM,OAAO,QAAgB,CAAA;AAGpC,eAAO,MAAM,WAAW;;;;;;;;;;;;;CAWvB,CAAA;AAID,eAAO,MAAM,SAAS;;;CAGrB,CAAA"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,IAAI,CAAA;AAUpC,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;iBAiBsB,eAAe,EAAE;;CAEjE,CAAA;AACD,eAAO,MAAM,WAAW,QAA8C,CAAA;AACtE,eAAO,MAAM,YAAY,QAA8B,CAAA;AACvD,eAAO,MAAM,OAAO,QAAgB,CAAA;AAGpC,eAAO,MAAM,WAAW;;;;;;;;;;;;;;CAYvB,CAAA;AAID,eAAO,MAAM,SAAS;;;CAGrB,CAAA"}
package/dist/constants.js CHANGED
@@ -10,12 +10,12 @@ var __rest = (this && this.__rest) || function (s, e) {
10
10
  }
11
11
  return t;
12
12
  };
13
- var _a, _b;
13
+ var _a, _b, _c;
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.S3_CONFIG = exports.AUTH_CONFIG = exports.DB_NAME = exports.HTTPS_SCHEMA = exports.API_VERSION = exports.DEFAULT_CONFIG = void 0;
16
16
  const utils_1 = require("./auth/utils");
17
17
  const { database_name, collection_name = 'users', user_id_field = 'id', on_user_creation_function_name } = (0, utils_1.loadCustomUserData)();
18
- const _c = (0, utils_1.loadAuthConfig)(), { auth_collection = 'auth_users' } = _c, configuration = __rest(_c, ["auth_collection"]);
18
+ const _d = (0, utils_1.loadAuthConfig)(), { auth_collection = 'auth_users' } = _d, configuration = __rest(_d, ["auth_collection"]);
19
19
  exports.DEFAULT_CONFIG = {
20
20
  PORT: Number(process.env.PORT) || 3000,
21
21
  MONGODB_URL: process.env.MONGODB_URL || '',
@@ -46,10 +46,11 @@ exports.AUTH_CONFIG = {
46
46
  resetPasswordCollection: 'reset_password_requests',
47
47
  refreshTokensCollection: 'auth_refresh_tokens',
48
48
  resetPasswordConfig: (_a = configuration['local-userpass']) === null || _a === void 0 ? void 0 : _a.config,
49
+ localUserpassConfig: (_b = configuration['local-userpass']) === null || _b === void 0 ? void 0 : _b.config,
49
50
  user_id_field,
50
51
  on_user_creation_function_name,
51
52
  providers: {
52
- "custom-function": (_b = configuration['custom-function']) === null || _b === void 0 ? void 0 : _b.config
53
+ "custom-function": (_c = configuration['custom-function']) === null || _c === void 0 ? void 0 : _c.config
53
54
  }
54
55
  };
55
56
  exports.S3_CONFIG = {
@@ -1 +1 @@
1
- {"version":3,"file":"handleUserRegistration.d.ts","sourceRoot":"","sources":["../../src/shared/handleUserRegistration.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAA;AAE9E;;;;;;GAMG;AACH,QAAA,MAAM,sBAAsB,EAAE,sBAmD7B,CAAA;AAED,eAAe,sBAAsB,CAAA"}
1
+ {"version":3,"file":"handleUserRegistration.d.ts","sourceRoot":"","sources":["../../src/shared/handleUserRegistration.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAA;AAE9E;;;;;;GAMG;AACH,QAAA,MAAM,sBAAsB,EAAE,sBAkI7B,CAAA;AAED,eAAe,sBAAsB,CAAA"}
@@ -10,6 +10,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  const constants_1 = require("../constants");
13
+ const state_1 = require("../state");
14
+ const context_1 = require("../utils/context");
13
15
  const crypto_1 = require("../utils/crypto");
14
16
  /**
15
17
  * Register user
@@ -19,11 +21,16 @@ const crypto_1 = require("../utils/crypto");
19
21
  * @returns {Promise<InsertOneResult<Document>>} A promise resolving to the result of the insert operation.
20
22
  */
21
23
  const handleUserRegistration = (app, opt) => (_a) => __awaiter(void 0, [_a], void 0, function* ({ email, password }) {
24
+ var _b;
22
25
  const { run_as_system, skipUserCheck, provider } = opt !== null && opt !== void 0 ? opt : {};
23
26
  if (!run_as_system) {
24
27
  throw new Error('only run_as_system');
25
28
  }
26
29
  const { authCollection } = constants_1.AUTH_CONFIG;
30
+ const localUserpassConfig = constants_1.AUTH_CONFIG.localUserpassConfig;
31
+ const autoConfirm = (localUserpassConfig === null || localUserpassConfig === void 0 ? void 0 : localUserpassConfig.autoConfirm) === true;
32
+ const runConfirmationFunction = (localUserpassConfig === null || localUserpassConfig === void 0 ? void 0 : localUserpassConfig.runConfirmationFunction) === true;
33
+ const confirmationFunctionName = localUserpassConfig === null || localUserpassConfig === void 0 ? void 0 : localUserpassConfig.confirmationFunctionName;
27
34
  const mongo = app === null || app === void 0 ? void 0 : app.mongo;
28
35
  const db = mongo.client.db(constants_1.DB_NAME);
29
36
  const hashedPassword = yield (0, crypto_1.hashPassword)(password);
@@ -34,7 +41,7 @@ const handleUserRegistration = (app, opt) => (_a) => __awaiter(void 0, [_a], voi
34
41
  const result = yield (db === null || db === void 0 ? void 0 : db.collection(authCollection).insertOne({
35
42
  email,
36
43
  password: hashedPassword,
37
- status: skipUserCheck ? 'confirmed' : 'pending',
44
+ status: skipUserCheck || autoConfirm ? 'confirmed' : 'pending',
38
45
  createdAt: new Date(),
39
46
  custom_data: {
40
47
  // TODO: aggiungere dati personalizzati alla registrazione
@@ -58,6 +65,64 @@ const handleUserRegistration = (app, opt) => (_a) => __awaiter(void 0, [_a], voi
58
65
  ]
59
66
  }
60
67
  }));
68
+ if (!(result === null || result === void 0 ? void 0 : result.insertedId) || skipUserCheck || autoConfirm) {
69
+ return result;
70
+ }
71
+ if (!runConfirmationFunction) {
72
+ throw new Error('Missing confirmation function');
73
+ }
74
+ if (!confirmationFunctionName) {
75
+ throw new Error('Missing confirmation function name');
76
+ }
77
+ const functionsList = state_1.StateManager.select('functions');
78
+ const services = state_1.StateManager.select('services');
79
+ const confirmationFunction = functionsList[confirmationFunctionName];
80
+ if (!confirmationFunction) {
81
+ throw new Error(`Confirmation function not found: ${confirmationFunctionName}`);
82
+ }
83
+ const token = (0, crypto_1.generateToken)();
84
+ const tokenId = (0, crypto_1.generateToken)();
85
+ yield (db === null || db === void 0 ? void 0 : db.collection(authCollection).updateOne({ _id: result.insertedId }, {
86
+ $set: {
87
+ confirmationToken: token,
88
+ confirmationTokenId: tokenId
89
+ }
90
+ }));
91
+ let confirmationStatus = 'fail';
92
+ try {
93
+ const response = yield (0, context_1.GenerateContext)({
94
+ args: [{
95
+ token,
96
+ tokenId,
97
+ username: email
98
+ }],
99
+ app,
100
+ rules: {},
101
+ user: {},
102
+ currentFunction: confirmationFunction,
103
+ functionsList,
104
+ services,
105
+ runAsSystem: true
106
+ });
107
+ confirmationStatus = (_b = response === null || response === void 0 ? void 0 : response.status) !== null && _b !== void 0 ? _b : 'fail';
108
+ }
109
+ catch (_c) {
110
+ confirmationStatus = 'fail';
111
+ }
112
+ if (confirmationStatus === 'success') {
113
+ yield (db === null || db === void 0 ? void 0 : db.collection(authCollection).updateOne({ _id: result.insertedId }, {
114
+ $set: { status: 'confirmed' },
115
+ $unset: { confirmationToken: '', confirmationTokenId: '' }
116
+ }));
117
+ return result;
118
+ }
119
+ if (confirmationStatus === 'pending') {
120
+ return result;
121
+ }
122
+ yield (db === null || db === void 0 ? void 0 : db.collection(authCollection).updateOne({ _id: result.insertedId }, {
123
+ $set: { status: 'failed' },
124
+ $unset: { confirmationToken: '', confirmationTokenId: '' }
125
+ }));
61
126
  return result;
62
127
  });
63
128
  exports.default = handleUserRegistration;
@@ -23,10 +23,10 @@ export declare const generateContextData: ({ user, services, app, rules, current
23
23
  method?: string | undefined;
24
24
  url?: string | undefined;
25
25
  host?: string | undefined;
26
- id?: string | undefined;
27
26
  ips?: string[];
28
27
  hostname?: string | undefined;
29
28
  ip?: string | undefined;
29
+ id?: string | undefined;
30
30
  };
31
31
  user: unknown;
32
32
  environment: {
@@ -69,16 +69,16 @@ export declare const generateContextData: ({ user, services, app, rules, current
69
69
  message: string;
70
70
  };
71
71
  } | import("undici").Dispatcher.ResponseData<T>>;
72
- } | {
73
- emailPasswordAuth: {
74
- registerUser: ReturnType<import("../../shared/models/handleUserRegistration.model").HandleUserRegistration>;
75
- };
76
72
  } | {
77
73
  lambda: (region: string) => import("aws-sdk").Lambda & {
78
74
  Invoke: (...args: Parameters<import("aws-sdk").Lambda["invoke"]>) => Promise<import("aws-sdk/lib/request").PromiseResult<import("aws-sdk/clients/lambda").InvocationResponse, import("aws-sdk").AWSError>>;
79
75
  InvokeAsync: import("aws-sdk").Lambda["invokeAsync"];
80
76
  };
81
77
  s3: (region: string) => import("aws-sdk").S3;
78
+ } | {
79
+ emailPasswordAuth: {
80
+ registerUser: ReturnType<import("../../shared/models/handleUserRegistration.model").HandleUserRegistration>;
81
+ };
82
82
  } | undefined;
83
83
  };
84
84
  functions: {
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/utils/context/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAE3C,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AAEvD;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAAI,0FASjC,yBAAyB;;;uBAGT,SAAS;yBAGP,SAAS;;;;;;;;;;;;;;;;;;uBAcb,MAAM;;;+BAGE,MAAM,OAAO,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAlCG,GAE3C;;;;;;;4BAiDgB,MAAM,OAAO,aAAa,WAAW,SAAS;;;CAclE,CAAA"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/utils/context/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAE3C,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AAEvD;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAAI,0FASjC,yBAAyB;;;uBAGT,SAAS;yBAGP,SAAS;;;;;;;;;;;;;;;;;;uBAcb,MAAM;;;+BAGE,MAAM,OAAO,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAlCG,GAE3C;;;;;;;;;;;4BAiDgB,MAAM,OAAO,aAAa,WAAW,SAAS;;;CAclE,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowerforce/flowerbase",
3
- "version": "1.2.1-beta.10",
3
+ "version": "1.2.1-beta.12",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,6 +1,6 @@
1
1
  import { FastifyInstance } from 'fastify'
2
+ import { ObjectId } from 'mongodb'
2
3
  import { AUTH_CONFIG, DB_NAME, DEFAULT_CONFIG } from '../../../constants'
3
- import { services } from '../../../services'
4
4
  import handleUserRegistration from '../../../shared/handleUserRegistration'
5
5
  import { PROVIDER } from '../../../shared/models/handleUserRegistration.model'
6
6
  import { StateManager } from '../../../state'
@@ -10,6 +10,7 @@ import {
10
10
  AUTH_ENDPOINTS,
11
11
  AUTH_ERRORS,
12
12
  CONFIRM_RESET_SCHEMA,
13
+ CONFIRM_USER_SCHEMA,
13
14
  LOGIN_SCHEMA,
14
15
  REGISTRATION_SCHEMA,
15
16
  RESET_CALL_SCHEMA,
@@ -17,6 +18,7 @@ import {
17
18
  } from '../../utils'
18
19
  import {
19
20
  ConfirmResetPasswordDto,
21
+ ConfirmUserDto,
20
22
  LoginDto,
21
23
  RegistrationDto,
22
24
  ResetPasswordCallDto,
@@ -142,6 +144,50 @@ export async function localUserPassController(app: FastifyInstance) {
142
144
  }
143
145
  )
144
146
 
147
+ /**
148
+ * Endpoint for confirming a user registration.
149
+ *
150
+ * @route {POST} /confirm
151
+ * @param {ConfirmUserDto} req - The request object with confirmation data.
152
+ * @returns {Promise<Object>} A promise resolving with confirmation status.
153
+ */
154
+ app.post<ConfirmUserDto>(
155
+ AUTH_ENDPOINTS.CONFIRM,
156
+ {
157
+ schema: CONFIRM_USER_SCHEMA
158
+ },
159
+ async (req, res) => {
160
+ const key = `confirm:${req.ip}`
161
+ if (isRateLimited(key, resetMaxAttempts, rateLimitWindowMs)) {
162
+ res.status(429).send({ message: 'Too many requests' })
163
+ return
164
+ }
165
+
166
+ const existing = await db.collection(authCollection!).findOne({
167
+ confirmationToken: req.body.token,
168
+ confirmationTokenId: req.body.tokenId
169
+ }) as { _id: ObjectId; status?: string } | null
170
+
171
+ if (!existing) {
172
+ res.status(500)
173
+ throw new Error(AUTH_ERRORS.INVALID_TOKEN)
174
+ }
175
+
176
+ if (existing.status !== 'confirmed') {
177
+ await db.collection(authCollection!).updateOne(
178
+ { _id: existing._id },
179
+ {
180
+ $set: { status: 'confirmed' },
181
+ $unset: { confirmationToken: '', confirmationTokenId: '' }
182
+ }
183
+ )
184
+ }
185
+
186
+ res.status(200)
187
+ return { status: 'confirmed' }
188
+ }
189
+ )
190
+
145
191
  /**
146
192
  * Endpoint for user login.
147
193
  *
@@ -192,19 +238,8 @@ export async function localUserPassController(app: FastifyInstance) {
192
238
  id: authUser._id.toString()
193
239
  }
194
240
 
195
- if (authUser && authUser.status === 'pending') {
196
- try {
197
- await db?.collection(authCollection!).updateOne(
198
- { _id: authUser._id },
199
- {
200
- $set: {
201
- status: 'confirmed'
202
- }
203
- }
204
- )
205
- } catch (error) {
206
- console.log('>>> 🚀 ~ localUserPassController ~ error:', error)
207
- }
241
+ if (authUser && authUser.status !== 'confirmed') {
242
+ throw new Error(AUTH_ERRORS.USER_NOT_CONFIRMED)
208
243
  }
209
244
 
210
245
  const refreshToken = this.createRefreshToken(userWithCustomData)
@@ -49,3 +49,10 @@ export interface ConfirmResetPasswordDto {
49
49
  password: string
50
50
  }
51
51
  }
52
+
53
+ export interface ConfirmUserDto {
54
+ Body: {
55
+ token: string
56
+ tokenId: string
57
+ }
58
+ }
package/src/auth/utils.ts CHANGED
@@ -64,6 +64,17 @@ export const CONFIRM_RESET_SCHEMA = {
64
64
  }
65
65
  }
66
66
 
67
+ export const CONFIRM_USER_SCHEMA = {
68
+ body: {
69
+ type: 'object',
70
+ properties: {
71
+ token: { type: 'string' },
72
+ tokenId: { type: 'string' }
73
+ },
74
+ required: ['token', 'tokenId']
75
+ }
76
+ }
77
+
67
78
  export const RESET_SCHEMA = RESET_SEND_SCHEMA
68
79
 
69
80
  export const REGISTRATION_SCHEMA = {
@@ -85,6 +96,7 @@ export const REGISTRATION_SCHEMA = {
85
96
  export enum AUTH_ENDPOINTS {
86
97
  LOGIN = '/login',
87
98
  REGISTRATION = '/register',
99
+ CONFIRM = '/confirm',
88
100
  PROFILE = '/profile',
89
101
  SESSION = '/session',
90
102
  RESET = '/reset/send',
@@ -97,7 +109,8 @@ export enum AUTH_ERRORS {
97
109
  INVALID_CREDENTIALS = 'Invalid credentials',
98
110
  INVALID_TOKEN = 'Invalid refresh token provided',
99
111
  INVALID_RESET_PARAMS = 'Invalid token or tokenId provided',
100
- MISSING_RESET_FUNCTION = 'Missing reset function'
112
+ MISSING_RESET_FUNCTION = 'Missing reset function',
113
+ USER_NOT_CONFIRMED = 'User not confirmed'
101
114
  }
102
115
 
103
116
  export interface AuthConfig {
@@ -130,6 +143,7 @@ interface CustomFunction {
130
143
 
131
144
  export interface Config {
132
145
  autoConfirm: boolean
146
+ confirmationFunctionName?: string
133
147
  resetFunctionName: string
134
148
  resetPasswordUrl: string
135
149
  runConfirmationFunction: boolean
package/src/constants.ts CHANGED
@@ -40,6 +40,7 @@ export const AUTH_CONFIG = {
40
40
  resetPasswordCollection: 'reset_password_requests',
41
41
  refreshTokensCollection: 'auth_refresh_tokens',
42
42
  resetPasswordConfig: configuration['local-userpass']?.config,
43
+ localUserpassConfig: configuration['local-userpass']?.config,
43
44
  user_id_field,
44
45
  on_user_creation_function_name,
45
46
  providers: {
@@ -1,5 +1,7 @@
1
1
  import { AUTH_CONFIG, DB_NAME } from "../constants"
2
- import { hashPassword } from "../utils/crypto"
2
+ import { StateManager } from "../state"
3
+ import { GenerateContext } from "../utils/context"
4
+ import { generateToken, hashPassword } from "../utils/crypto"
3
5
  import { HandleUserRegistration } from "./models/handleUserRegistration.model"
4
6
 
5
7
  /**
@@ -17,6 +19,10 @@ const handleUserRegistration: HandleUserRegistration = (app, opt) => async ({ em
17
19
  }
18
20
 
19
21
  const { authCollection } = AUTH_CONFIG
22
+ const localUserpassConfig = AUTH_CONFIG.localUserpassConfig
23
+ const autoConfirm = localUserpassConfig?.autoConfirm === true
24
+ const runConfirmationFunction = localUserpassConfig?.runConfirmationFunction === true
25
+ const confirmationFunctionName = localUserpassConfig?.confirmationFunctionName
20
26
  const mongo = app?.mongo
21
27
  const db = mongo.client.db(DB_NAME)
22
28
  const hashedPassword = await hashPassword(password)
@@ -29,7 +35,7 @@ const handleUserRegistration: HandleUserRegistration = (app, opt) => async ({ em
29
35
  const result = await db?.collection(authCollection!).insertOne({
30
36
  email,
31
37
  password: hashedPassword,
32
- status: skipUserCheck ? 'confirmed' : 'pending',
38
+ status: skipUserCheck || autoConfirm ? 'confirmed' : 'pending',
33
39
  createdAt: new Date(),
34
40
  custom_data: {
35
41
  // TODO: aggiungere dati personalizzati alla registrazione
@@ -58,6 +64,81 @@ const handleUserRegistration: HandleUserRegistration = (app, opt) => async ({ em
58
64
  }
59
65
  )
60
66
 
67
+ if (!result?.insertedId || skipUserCheck || autoConfirm) {
68
+ return result
69
+ }
70
+
71
+ if (!runConfirmationFunction) {
72
+ throw new Error('Missing confirmation function')
73
+ }
74
+
75
+ if (!confirmationFunctionName) {
76
+ throw new Error('Missing confirmation function name')
77
+ }
78
+
79
+ const functionsList = StateManager.select('functions')
80
+ const services = StateManager.select('services')
81
+ const confirmationFunction = functionsList[confirmationFunctionName]
82
+ if (!confirmationFunction) {
83
+ throw new Error(`Confirmation function not found: ${confirmationFunctionName}`)
84
+ }
85
+
86
+ const token = generateToken()
87
+ const tokenId = generateToken()
88
+ await db?.collection(authCollection!).updateOne(
89
+ { _id: result.insertedId },
90
+ {
91
+ $set: {
92
+ confirmationToken: token,
93
+ confirmationTokenId: tokenId
94
+ }
95
+ }
96
+ )
97
+
98
+ type ConfirmationResult = { status?: 'success' | 'pending' | 'fail' }
99
+ let confirmationStatus: ConfirmationResult['status'] = 'fail'
100
+ try {
101
+ const response = await GenerateContext({
102
+ args: [{
103
+ token,
104
+ tokenId,
105
+ username: email
106
+ }],
107
+ app,
108
+ rules: {},
109
+ user: {},
110
+ currentFunction: confirmationFunction,
111
+ functionsList,
112
+ services,
113
+ runAsSystem: true
114
+ }) as ConfirmationResult
115
+ confirmationStatus = response?.status ?? 'fail'
116
+ } catch {
117
+ confirmationStatus = 'fail'
118
+ }
119
+
120
+ if (confirmationStatus === 'success') {
121
+ await db?.collection(authCollection!).updateOne(
122
+ { _id: result.insertedId },
123
+ {
124
+ $set: { status: 'confirmed' },
125
+ $unset: { confirmationToken: '', confirmationTokenId: '' }
126
+ }
127
+ )
128
+ return result
129
+ }
130
+
131
+ if (confirmationStatus === 'pending') {
132
+ return result
133
+ }
134
+
135
+ await db?.collection(authCollection!).updateOne(
136
+ { _id: result.insertedId },
137
+ {
138
+ $set: { status: 'failed' },
139
+ $unset: { confirmationToken: '', confirmationTokenId: '' }
140
+ }
141
+ )
61
142
  return result
62
143
 
63
144
  }