@flowerforce/flowerbase 1.4.2-beta.0 → 1.4.2-beta.2

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;AAqCzC;;;;GAIG;AACH,wBAAsB,uBAAuB,CAAC,GAAG,EAAE,eAAe,iBAsUjE"}
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,iBAqVjE"}
@@ -107,7 +107,23 @@ function localUserPassController(app) {
107
107
  res.status(429).send({ message: 'Too many requests' });
108
108
  return;
109
109
  }
110
- 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 });
110
+ let result;
111
+ try {
112
+ result = yield (0, handleUserRegistration_1.default)(app, { run_as_system: true, provider: handleUserRegistration_model_1.PROVIDER.LOCAL_USERPASS })({
113
+ email: req.body.email.toLowerCase(),
114
+ password: req.body.password
115
+ });
116
+ }
117
+ catch (error) {
118
+ if (error instanceof Error && error.message === 'This email address is already used') {
119
+ res.status(409).send({
120
+ error: 'name already in use',
121
+ error_code: 'AccountNameInUse'
122
+ });
123
+ return;
124
+ }
125
+ throw error;
126
+ }
111
127
  if (!(result === null || result === void 0 ? void 0 : result.insertedId)) {
112
128
  res === null || res === void 0 ? void 0 : res.status(500);
113
129
  throw new Error('Failed to register user');
@@ -22,7 +22,7 @@ type Config = {
22
22
  isAutoTrigger?: boolean;
23
23
  match: Record<string, unknown>;
24
24
  operation_types: string[];
25
- operation_type?: 'CREATE' | 'DELETE';
25
+ operation_type?: 'CREATE' | 'DELETE' | 'LOGOUT';
26
26
  project: Record<string, unknown>;
27
27
  service_name: string;
28
28
  skip_catchup_events: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/features/triggers/interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AACnD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAE5D,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,WAAW,CAAA;IACjB,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,gBAAgB,EAAE;QAChB,QAAQ,EAAE;YACR,MAAM,EAAE;gBACN,aAAa,EAAE,MAAM,CAAA;aACtB,CAAA;SACF,CAAA;KACF,CAAA;CACF;AAED,KAAK,MAAM,GAAG;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,EAAE,OAAO,CAAA;IACtB,2BAA2B,EAAE,OAAO,CAAA;IACpC,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB,cAAc,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAA;IACpC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAChC,YAAY,EAAE,MAAM,CAAA;IACpB,mBAAmB,EAAE,OAAO,CAAA;IAC5B,sBAAsB,EAAE,OAAO,CAAA;IAC/B,SAAS,EAAE,OAAO,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,UAAU,GAAG,gBAAgB,CAAA;AACrE,MAAM,MAAM,QAAQ,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,EAAE,CAAA;AAE/D,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,EAAE,QAAQ,CAAA;IACxB,GAAG,EAAE,eAAe,CAAA;IACpB,QAAQ,EAAE,QAAQ,CAAA;IAClB,aAAa,EAAE,SAAS,CAAA;CACzB,CAAA"}
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../../src/features/triggers/interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AACnD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAE5D,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,WAAW,CAAA;IACjB,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,gBAAgB,EAAE;QAChB,QAAQ,EAAE;YACR,MAAM,EAAE;gBACN,aAAa,EAAE,MAAM,CAAA;aACtB,CAAA;SACF,CAAA;KACF,CAAA;CACF;AAED,KAAK,MAAM,GAAG;IACZ,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,aAAa,EAAE,OAAO,CAAA;IACtB,2BAA2B,EAAE,OAAO,CAAA;IACpC,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB,cAAc,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAA;IAC/C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAChC,YAAY,EAAE,MAAM,CAAA;IACpB,mBAAmB,EAAE,OAAO,CAAA;IAC5B,sBAAsB,EAAE,OAAO,CAAA;IAC/B,SAAS,EAAE,OAAO,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG,WAAW,GAAG,UAAU,GAAG,gBAAgB,CAAA;AACrE,MAAM,MAAM,QAAQ,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,EAAE,CAAA;AAE/D,MAAM,MAAM,aAAa,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,EAAE,QAAQ,CAAA;IACxB,GAAG,EAAE,eAAe,CAAA;IACpB,QAAQ,EAAE,QAAQ,CAAA;IAClB,aAAa,EAAE,SAAS,CAAA;CACzB,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/features/triggers/utils.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,aAAa,EAAW,QAAQ,EAAE,MAAM,aAAa,CAAA;AAqC9D;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,GAAU,gBAAuB,KAAG,OAAO,CAAC,QAAQ,CAkB5E,CAAA;AA8VD,eAAO,MAAM,gBAAgB;0EA1U1B,aAAa;yEAqRb,aAAa;+EA3Pb,aAAa;CAoTf,CAAA"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/features/triggers/utils.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,aAAa,EAAW,QAAQ,EAAE,MAAM,aAAa,CAAA;AAqC9D;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,GAAU,gBAAuB,KAAG,OAAO,CAAC,QAAQ,CAkB5E,CAAA;AAuYD,eAAO,MAAM,gBAAgB;0EAnX1B,aAAa;yEA8Tb,aAAa;+EAnSb,aAAa;CA4Vf,CAAA"}
@@ -120,6 +120,7 @@ const handleCronTrigger = (_a) => __awaiter(void 0, [_a], void 0, function* ({ c
120
120
  const mapOpInverse = {
121
121
  CREATE: ['insert', 'update', 'replace'],
122
122
  DELETE: ['delete'],
123
+ LOGOUT: ['update'],
123
124
  };
124
125
  const handleAuthenticationTrigger = (_a) => __awaiter(void 0, [_a], void 0, function* ({ config, triggerHandler, functionsList, services, app }) {
125
126
  var _b;
@@ -150,7 +151,7 @@ const handleAuthenticationTrigger = (_a) => __awaiter(void 0, [_a], void 0, func
150
151
  });
151
152
  changeStream.on('change', function (change) {
152
153
  return __awaiter(this, void 0, void 0, function* () {
153
- var _a, _b;
154
+ var _a;
154
155
  const operationType = change['operationType'];
155
156
  const documentKey = change['documentKey'];
156
157
  const fullDocument = change['fullDocument'];
@@ -159,11 +160,13 @@ const handleAuthenticationTrigger = (_a) => __awaiter(void 0, [_a], void 0, func
159
160
  return;
160
161
  }
161
162
  const updateDescription = change['updateDescription'];
162
- const updatedStatus = (_a = updateDescription === null || updateDescription === void 0 ? void 0 : updateDescription.updatedFields) === null || _a === void 0 ? void 0 : _a.status;
163
+ const updatedFields = updateDescription === null || updateDescription === void 0 ? void 0 : updateDescription.updatedFields;
164
+ const updatedStatus = updatedFields === null || updatedFields === void 0 ? void 0 : updatedFields.status;
163
165
  const isInsert = operationType === 'insert';
164
166
  const isUpdate = operationType === 'update';
165
167
  const isReplace = operationType === 'replace';
166
168
  const isDelete = operationType === 'delete';
169
+ const isLogoutUpdate = isUpdate && !!updatedFields && 'lastLogoutAt' in updatedFields;
167
170
  let confirmedCandidate = false;
168
171
  let confirmedDocument = fullDocument;
169
172
  const buildUserData = (document) => {
@@ -189,6 +192,44 @@ const handleAuthenticationTrigger = (_a) => __awaiter(void 0, [_a], void 0, func
189
192
  email: currentUser.email
190
193
  } });
191
194
  };
195
+ if (operation_type === 'LOGOUT') {
196
+ if (!isLogoutUpdate) {
197
+ return;
198
+ }
199
+ let logoutDocument = fullDocument !== null && fullDocument !== void 0 ? fullDocument : confirmedDocument;
200
+ if (!logoutDocument && (documentKey === null || documentKey === void 0 ? void 0 : documentKey._id)) {
201
+ logoutDocument = (yield collection.findOne({
202
+ _id: documentKey._id
203
+ }));
204
+ }
205
+ const userData = buildUserData(logoutDocument);
206
+ if (!userData) {
207
+ return;
208
+ }
209
+ const op = {
210
+ operationType: 'LOGOUT',
211
+ fullDocument,
212
+ fullDocumentBeforeChange,
213
+ documentKey,
214
+ updateDescription
215
+ };
216
+ try {
217
+ yield (0, context_1.GenerateContext)({
218
+ args: [Object.assign({ user: userData }, op)],
219
+ app,
220
+ rules: state_1.StateManager.select("rules"),
221
+ user: {}, // TODO from currentUser ??
222
+ currentFunction: triggerHandler,
223
+ functionsList,
224
+ services,
225
+ runAsSystem: true
226
+ });
227
+ }
228
+ catch (error) {
229
+ console.log("🚀 ~ handleAuthenticationTrigger ~ error:", error);
230
+ }
231
+ return;
232
+ }
192
233
  if (isDelete) {
193
234
  if (isAutoTrigger || operation_type !== 'DELETE') {
194
235
  return;
@@ -279,7 +320,7 @@ const handleAuthenticationTrigger = (_a) => __awaiter(void 0, [_a], void 0, func
279
320
  }, {
280
321
  returnDocument: 'after'
281
322
  });
282
- const document = (_b = updateResult === null || updateResult === void 0 ? void 0 : updateResult.value) !== null && _b !== void 0 ? _b : confirmedDocument;
323
+ const document = (_a = updateResult === null || updateResult === void 0 ? void 0 : updateResult.value) !== null && _a !== void 0 ? _a : confirmedDocument;
283
324
  if (!document) {
284
325
  return;
285
326
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowerforce/flowerbase",
3
- "version": "1.4.2-beta.0",
3
+ "version": "1.4.2-beta.2",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -138,7 +138,22 @@ export async function localUserPassController(app: FastifyInstance) {
138
138
  return
139
139
  }
140
140
 
141
- const result = await handleUserRegistration(app, { run_as_system: true, provider: PROVIDER.LOCAL_USERPASS })({ email: req.body.email.toLowerCase(), password: req.body.password })
141
+ let result
142
+ try {
143
+ result = await handleUserRegistration(app, { run_as_system: true, provider: PROVIDER.LOCAL_USERPASS })({
144
+ email: req.body.email.toLowerCase(),
145
+ password: req.body.password
146
+ })
147
+ } catch (error) {
148
+ if (error instanceof Error && error.message === 'This email address is already used') {
149
+ res.status(409).send({
150
+ error: 'name already in use',
151
+ error_code: 'AccountNameInUse'
152
+ })
153
+ return
154
+ }
155
+ throw error
156
+ }
142
157
 
143
158
  if (!result?.insertedId) {
144
159
  res?.status(500)
@@ -24,7 +24,7 @@ type Config = {
24
24
  isAutoTrigger?: boolean
25
25
  match: Record<string, unknown>
26
26
  operation_types: string[]
27
- operation_type?: 'CREATE' | 'DELETE'
27
+ operation_type?: 'CREATE' | 'DELETE' | 'LOGOUT'
28
28
  project: Record<string, unknown>
29
29
  service_name: string
30
30
  skip_catchup_events: boolean
@@ -106,6 +106,7 @@ const handleCronTrigger = async ({
106
106
  const mapOpInverse = {
107
107
  CREATE: ['insert', 'update', 'replace'],
108
108
  DELETE: ['delete'],
109
+ LOGOUT: ['update'],
109
110
  }
110
111
 
111
112
  const handleAuthenticationTrigger = async ({
@@ -161,11 +162,13 @@ const handleAuthenticationTrigger = async ({
161
162
  const updateDescription = change[
162
163
  'updateDescription' as keyof typeof change
163
164
  ] as { updatedFields?: Record<string, unknown> } | undefined
164
- const updatedStatus = updateDescription?.updatedFields?.status
165
+ const updatedFields = updateDescription?.updatedFields
166
+ const updatedStatus = updatedFields?.status
165
167
  const isInsert = operationType === 'insert'
166
168
  const isUpdate = operationType === 'update'
167
169
  const isReplace = operationType === 'replace'
168
170
  const isDelete = operationType === 'delete'
171
+ const isLogoutUpdate = isUpdate && !!updatedFields && 'lastLogoutAt' in updatedFields
169
172
 
170
173
  let confirmedCandidate = false
171
174
  let confirmedDocument =
@@ -199,6 +202,44 @@ const handleAuthenticationTrigger = async ({
199
202
  }
200
203
  }
201
204
 
205
+ if (operation_type === 'LOGOUT') {
206
+ if (!isLogoutUpdate) {
207
+ return
208
+ }
209
+ let logoutDocument = fullDocument ?? confirmedDocument
210
+ if (!logoutDocument && documentKey?._id) {
211
+ logoutDocument = await collection.findOne({
212
+ _id: documentKey._id
213
+ }) as Record<string, unknown> | null
214
+ }
215
+ const userData = buildUserData(logoutDocument)
216
+ if (!userData) {
217
+ return
218
+ }
219
+ const op = {
220
+ operationType: 'LOGOUT',
221
+ fullDocument,
222
+ fullDocumentBeforeChange,
223
+ documentKey,
224
+ updateDescription
225
+ }
226
+ try {
227
+ await GenerateContext({
228
+ args: [{ user: userData, ...op }],
229
+ app,
230
+ rules: StateManager.select("rules"),
231
+ user: {}, // TODO from currentUser ??
232
+ currentFunction: triggerHandler,
233
+ functionsList,
234
+ services,
235
+ runAsSystem: true
236
+ })
237
+ } catch (error) {
238
+ console.log("🚀 ~ handleAuthenticationTrigger ~ error:", error)
239
+ }
240
+ return
241
+ }
242
+
202
243
  if (isDelete) {
203
244
  if (isAutoTrigger || operation_type !== 'DELETE') {
204
245
  return