@flowerforce/flowerbase 1.7.6-beta.3 → 1.7.6-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/providers/anon-user/controller.d.ts.map +1 -1
- package/dist/auth/providers/anon-user/controller.js +1 -0
- package/dist/auth/providers/custom-function/controller.d.ts.map +1 -1
- package/dist/auth/providers/custom-function/controller.js +3 -1
- package/dist/auth/providers/local-userpass/controller.d.ts.map +1 -1
- package/dist/auth/providers/local-userpass/controller.js +3 -1
- package/dist/features/triggers/interface.d.ts +1 -1
- package/dist/features/triggers/interface.d.ts.map +1 -1
- package/dist/features/triggers/utils.d.ts.map +1 -1
- package/dist/features/triggers/utils.js +60 -0
- package/dist/utils/context/helpers.d.ts.map +1 -1
- package/dist/utils/context/helpers.js +3 -2
- package/dist/utils/context/index.d.ts.map +1 -1
- package/dist/utils/context/index.js +4 -2
- package/package.json +1 -1
- package/src/auth/providers/anon-user/controller.ts +1 -0
- package/src/auth/providers/custom-function/controller.ts +6 -1
- package/src/auth/providers/local-userpass/controller.ts +6 -1
- package/src/features/triggers/interface.ts +1 -1
- package/src/features/triggers/utils.ts +60 -0
- package/src/utils/__tests__/contextExecuteCompatibility.test.ts +27 -1
- package/src/utils/__tests__/generateContextData.test.ts +5 -1
- package/src/utils/context/helpers.ts +3 -2
- package/src/utils/context/index.ts +4 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/anon-user/controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAOzC;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,eAAe,
|
|
1
|
+
{"version":3,"file":"controller.d.ts","sourceRoot":"","sources":["../../../../src/auth/providers/anon-user/controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAOzC;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,eAAe,iBAyE5D"}
|
|
@@ -1 +1 @@
|
|
|
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;AAUzC;;;;GAIG;AACH,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,eAAe,
|
|
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;AAUzC;;;;GAIG;AACH,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,eAAe,iBA0IlE"}
|
|
@@ -111,15 +111,17 @@ function customFunctionController(app) {
|
|
|
111
111
|
user_data: Object.assign(Object.assign({}, (user || {})), { id: authUser._id.toString(), email: authUser.email }),
|
|
112
112
|
custom_data: Object.assign({}, (user || {}))
|
|
113
113
|
};
|
|
114
|
+
const now = new Date();
|
|
114
115
|
const refreshToken = this.createRefreshToken(currentUserData);
|
|
115
116
|
const refreshTokenHash = (0, crypto_1.hashToken)(refreshToken);
|
|
116
117
|
yield authDb.collection(refreshTokensCollection).insertOne({
|
|
117
118
|
userId: authUser._id,
|
|
118
119
|
tokenHash: refreshTokenHash,
|
|
119
|
-
createdAt:
|
|
120
|
+
createdAt: now,
|
|
120
121
|
expiresAt: new Date(Date.now() + refreshTokenTtlMs),
|
|
121
122
|
revokedAt: null
|
|
122
123
|
});
|
|
124
|
+
yield authDb.collection(authCollection).updateOne({ _id: authUser._id }, { $set: { lastLoginAt: now } });
|
|
123
125
|
return {
|
|
124
126
|
access_token: this.createAccessToken(currentUserData),
|
|
125
127
|
refresh_token: refreshToken,
|
|
@@ -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,
|
|
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,iBA0XjE"}
|
|
@@ -214,15 +214,17 @@ function localUserPassController(app) {
|
|
|
214
214
|
if (authUser && authUser.status !== 'confirmed') {
|
|
215
215
|
throw new Error(utils_1.AUTH_ERRORS.USER_NOT_CONFIRMED);
|
|
216
216
|
}
|
|
217
|
+
const now = new Date();
|
|
217
218
|
const refreshToken = this.createRefreshToken(userWithCustomData);
|
|
218
219
|
const refreshTokenHash = (0, crypto_1.hashToken)(refreshToken);
|
|
219
220
|
yield authDb.collection(refreshTokensCollection).insertOne({
|
|
220
221
|
userId: authUser._id,
|
|
221
222
|
tokenHash: refreshTokenHash,
|
|
222
|
-
createdAt:
|
|
223
|
+
createdAt: now,
|
|
223
224
|
expiresAt: new Date(Date.now() + refreshTokenTtlMs),
|
|
224
225
|
revokedAt: null
|
|
225
226
|
});
|
|
227
|
+
yield authDb.collection(authCollection).updateOne({ _id: authUser._id }, { $set: { lastLoginAt: now } });
|
|
226
228
|
return {
|
|
227
229
|
access_token: this.createAccessToken(userWithCustomData),
|
|
228
230
|
refresh_token: refreshToken,
|
|
@@ -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' | 'LOGOUT';
|
|
25
|
+
operation_type?: 'CREATE' | 'DELETE' | 'LOGIN' | 'LOGOUT';
|
|
26
26
|
providers?: string[];
|
|
27
27
|
project: Record<string, unknown>;
|
|
28
28
|
service_name: string;
|
|
@@ -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,GAAG,QAAQ,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,OAAO,GAAG,QAAQ,CAAA;IACzD,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,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;IACxB,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,WAAW,CAAA;IACxB,YAAY,EAAE,MAAM,CAAA;CACrB,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/features/triggers/utils.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,aAAa,EAAW,QAAQ,EAAE,MAAM,aAAa,CAAA;AA0E9D;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,GAAU,gBAAuB,KAAG,OAAO,CAAC,QAAQ,CAkB5E,CAAA;
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/features/triggers/utils.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,aAAa,EAAW,QAAQ,EAAE,MAAM,aAAa,CAAA;AA0E9D;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,GAAU,gBAAuB,KAAG,OAAO,CAAC,QAAQ,CAkB5E,CAAA;AA2qBD,eAAO,MAAM,gBAAgB;kHAppB1B,aAAa;iHA4jBb,aAAa;uHA1cb,aAAa;CAsiBf,CAAA"}
|
|
@@ -170,6 +170,7 @@ const handleCronTrigger = (_a) => __awaiter(void 0, [_a], void 0, function* ({ c
|
|
|
170
170
|
const mapOpInverse = {
|
|
171
171
|
CREATE: ['insert', 'update', 'replace'],
|
|
172
172
|
DELETE: ['delete'],
|
|
173
|
+
LOGIN: ['insert', 'update'],
|
|
173
174
|
LOGOUT: ['update'],
|
|
174
175
|
};
|
|
175
176
|
const normalizeOperationTypes = (operationTypes = []) => operationTypes.map((op) => op.toLowerCase());
|
|
@@ -270,6 +271,8 @@ const handleAuthenticationTrigger = (_a) => __awaiter(void 0, [_a], void 0, func
|
|
|
270
271
|
const isUpdate = operationType === 'update';
|
|
271
272
|
const isReplace = operationType === 'replace';
|
|
272
273
|
const isDelete = operationType === 'delete';
|
|
274
|
+
const isLoginInsert = isInsert && !!(fullDocument === null || fullDocument === void 0 ? void 0 : fullDocument.lastLoginAt);
|
|
275
|
+
const isLoginUpdate = isUpdate && !!updatedFields && 'lastLoginAt' in updatedFields;
|
|
273
276
|
const isLogoutUpdate = isUpdate && !!updatedFields && 'lastLogoutAt' in updatedFields;
|
|
274
277
|
let confirmedCandidate = false;
|
|
275
278
|
let confirmedDocument = fullDocument;
|
|
@@ -353,6 +356,63 @@ const handleAuthenticationTrigger = (_a) => __awaiter(void 0, [_a], void 0, func
|
|
|
353
356
|
}
|
|
354
357
|
return;
|
|
355
358
|
}
|
|
359
|
+
if (operation_type === 'LOGIN') {
|
|
360
|
+
if (!isLoginInsert && !isLoginUpdate) {
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
let loginDocument = fullDocument !== null && fullDocument !== void 0 ? fullDocument : confirmedDocument;
|
|
364
|
+
if (!loginDocument && (documentKey === null || documentKey === void 0 ? void 0 : documentKey._id)) {
|
|
365
|
+
loginDocument = (yield collection.findOne({
|
|
366
|
+
_id: documentKey._id
|
|
367
|
+
}));
|
|
368
|
+
}
|
|
369
|
+
if (!matchesProviderFilter(loginDocument, providerFilter)) {
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
const userData = buildUserData(loginDocument);
|
|
373
|
+
if (!userData) {
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
const op = {
|
|
377
|
+
operationType: 'LOGIN',
|
|
378
|
+
fullDocument,
|
|
379
|
+
fullDocumentBeforeChange,
|
|
380
|
+
documentKey,
|
|
381
|
+
updateDescription
|
|
382
|
+
};
|
|
383
|
+
try {
|
|
384
|
+
emitTriggerEvent({
|
|
385
|
+
status: 'fired',
|
|
386
|
+
triggerName,
|
|
387
|
+
triggerType,
|
|
388
|
+
functionName,
|
|
389
|
+
meta: Object.assign(Object.assign({}, baseMeta), { event: 'LOGIN' })
|
|
390
|
+
});
|
|
391
|
+
yield (0, context_1.GenerateContext)({
|
|
392
|
+
args: [Object.assign({ user: userData }, op)],
|
|
393
|
+
app,
|
|
394
|
+
rules: state_1.StateManager.select("rules"),
|
|
395
|
+
user: {}, // TODO from currentUser ??
|
|
396
|
+
currentFunction: triggerHandler,
|
|
397
|
+
functionName,
|
|
398
|
+
functionsList,
|
|
399
|
+
services,
|
|
400
|
+
runAsSystem: true
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
catch (error) {
|
|
404
|
+
emitTriggerEvent({
|
|
405
|
+
status: 'error',
|
|
406
|
+
triggerName,
|
|
407
|
+
triggerType,
|
|
408
|
+
functionName,
|
|
409
|
+
meta: Object.assign(Object.assign({}, baseMeta), { event: 'LOGIN' }),
|
|
410
|
+
error
|
|
411
|
+
});
|
|
412
|
+
console.log("🚀 ~ handleAuthenticationTrigger ~ error:", error);
|
|
413
|
+
}
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
356
416
|
if (isDelete) {
|
|
357
417
|
if (isAutoTrigger || operation_type !== 'DELETE') {
|
|
358
418
|
return;
|
|
@@ -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;AAG1C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAE3C,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AAEvD,KAAK,QAAQ,GAAG;IACd,MAAM,EAAE,CACN,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,GAAG,MAAM,EACvB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KACzC,MAAM,CAAA;IACX,MAAM,EAAE,CACN,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,GAAG,MAAM,EACpB,YAAY,CAAC,EAAE,OAAO,EACtB,sBAAsB,CAAC,EAAE,MAAM,EAAE,KAC9B,OAAO,CAAA;CACb,CAAA;AAgFD;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAAI,4GAUjC,yBAAyB;;;;;;;;;;;;;uBA4DP,SAAS;yBAGP,SAAS;;;;;;;;;;;;;;;;;;uBAcb,MAAM;;;;;;+BA5CU,MAAM,OAAO,QAAQ;;;;sCA1HrC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BAsGT,CAAC;iCAAa,CAAC;;;;;;;;;;;;;;;;;;;kCAtGP,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAsGT,CAAC;6BAAa,CAAC;;;;;;;;;;;;;;;;;;kCAtGP,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAsGT,CAAC;6BAAa,CAAC;;;;;;;;;;;;;;;4BAyEF,MAAM,OAAO,aAAa,WAAW,SAAS;;;
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/utils/context/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAA;AAG1C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAE3C,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AAEvD,KAAK,QAAQ,GAAG;IACd,MAAM,EAAE,CACN,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,GAAG,MAAM,EACvB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KACzC,MAAM,CAAA;IACX,MAAM,EAAE,CACN,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,GAAG,MAAM,EACpB,YAAY,CAAC,EAAE,OAAO,EACtB,sBAAsB,CAAC,EAAE,MAAM,EAAE,KAC9B,OAAO,CAAA;CACb,CAAA;AAgFD;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAAI,4GAUjC,yBAAyB;;;;;;;;;;;;;uBA4DP,SAAS;yBAGP,SAAS;;;;;;;;;;;;;;;;;;uBAcb,MAAM;;;;;;+BA5CU,MAAM,OAAO,QAAQ;;;;sCA1HrC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BAsGT,CAAC;iCAAa,CAAC;;;;;;;;;;;;;;;;;;;kCAtGP,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAsGT,CAAC;6BAAa,CAAC;;;;;;;;;;;;;;;;;;kCAtGP,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAsGT,CAAC;6BAAa,CAAC;;;;;;;;;;;;;;;4BAyEF,MAAM,OAAO,aAAa,WAAW,SAAS;;;CAkBrE,CAAA"}
|
|
@@ -176,16 +176,17 @@ const generateContextData = ({ user, services, app, rules, currentFunction, func
|
|
|
176
176
|
https: getService('api'),
|
|
177
177
|
functions: {
|
|
178
178
|
execute: (name, ...args) => {
|
|
179
|
-
const
|
|
179
|
+
const targetFunction = functionsList[name];
|
|
180
180
|
return GenerateContextSync({
|
|
181
181
|
args,
|
|
182
182
|
app,
|
|
183
183
|
rules,
|
|
184
184
|
user,
|
|
185
|
-
currentFunction,
|
|
185
|
+
currentFunction: targetFunction,
|
|
186
186
|
functionName: String(name),
|
|
187
187
|
functionsList,
|
|
188
188
|
services,
|
|
189
|
+
runAsSystem: currentFunction.run_as_system,
|
|
189
190
|
deserializeArgs: false
|
|
190
191
|
});
|
|
191
192
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/context/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AA4JnD;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CAAC,EACpC,IAAI,EACJ,GAAG,EACH,KAAK,EACL,IAAI,EACJ,eAAe,EACf,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,eAAsB,EACtB,OAAO,EACP,OAAO,EACR,EAAE,qBAAqB,GAAG,OAAO,CAAC,OAAO,CAAC,CA2G1C;AAED,wBAAgB,mBAAmB,CAAC,EAClC,IAAI,EACJ,GAAG,EACH,KAAK,EACL,IAAI,EACJ,eAAe,EACf,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,eAAsB,EACtB,OAAO,EACR,EAAE,qBAAqB,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/context/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AA4JnD;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CAAC,EACpC,IAAI,EACJ,GAAG,EACH,KAAK,EACL,IAAI,EACJ,eAAe,EACf,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,eAAsB,EACtB,OAAO,EACP,OAAO,EACR,EAAE,qBAAqB,GAAG,OAAO,CAAC,OAAO,CAAC,CA2G1C;AAED,wBAAgB,mBAAmB,CAAC,EAClC,IAAI,EACJ,GAAG,EACH,KAAK,EACL,IAAI,EACJ,eAAe,EACf,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,eAAsB,EACtB,OAAO,EACR,EAAE,qBAAqB,GAAG,OAAO,CA6BjC"}
|
|
@@ -153,7 +153,8 @@ function GenerateContext(_a) {
|
|
|
153
153
|
if (!currentFunction)
|
|
154
154
|
return;
|
|
155
155
|
const functionsQueue = state_1.StateManager.select("functionsQueue");
|
|
156
|
-
const
|
|
156
|
+
const effectiveRunAsSystem = Boolean(runAsSystem || currentFunction.run_as_system);
|
|
157
|
+
const functionToRun = Object.assign(Object.assign({}, currentFunction), { run_as_system: effectiveRunAsSystem });
|
|
157
158
|
const run = () => __awaiter(this, void 0, void 0, function* () {
|
|
158
159
|
var _a;
|
|
159
160
|
const contextData = (0, helpers_1.generateContextData)({
|
|
@@ -232,7 +233,8 @@ function GenerateContextSync({ args, app, rules, user, currentFunction, function
|
|
|
232
233
|
var _a;
|
|
233
234
|
if (!currentFunction)
|
|
234
235
|
return;
|
|
235
|
-
const
|
|
236
|
+
const effectiveRunAsSystem = Boolean(runAsSystem || currentFunction.run_as_system);
|
|
237
|
+
const functionToRun = Object.assign(Object.assign({}, currentFunction), { run_as_system: effectiveRunAsSystem });
|
|
236
238
|
const contextData = (0, helpers_1.generateContextData)({
|
|
237
239
|
user,
|
|
238
240
|
services,
|
package/package.json
CHANGED
|
@@ -128,15 +128,20 @@ export async function customFunctionController(app: FastifyInstance) {
|
|
|
128
128
|
...(user || {})
|
|
129
129
|
}
|
|
130
130
|
}
|
|
131
|
+
const now = new Date()
|
|
131
132
|
const refreshToken = this.createRefreshToken(currentUserData)
|
|
132
133
|
const refreshTokenHash = hashToken(refreshToken)
|
|
133
134
|
await authDb.collection(refreshTokensCollection).insertOne({
|
|
134
135
|
userId: authUser._id,
|
|
135
136
|
tokenHash: refreshTokenHash,
|
|
136
|
-
createdAt:
|
|
137
|
+
createdAt: now,
|
|
137
138
|
expiresAt: new Date(Date.now() + refreshTokenTtlMs),
|
|
138
139
|
revokedAt: null
|
|
139
140
|
})
|
|
141
|
+
await authDb.collection(authCollection!).updateOne(
|
|
142
|
+
{ _id: authUser._id },
|
|
143
|
+
{ $set: { lastLoginAt: now } }
|
|
144
|
+
)
|
|
140
145
|
return {
|
|
141
146
|
access_token: this.createAccessToken(currentUserData),
|
|
142
147
|
refresh_token: refreshToken,
|
|
@@ -283,15 +283,20 @@ export async function localUserPassController(app: FastifyInstance) {
|
|
|
283
283
|
throw new Error(AUTH_ERRORS.USER_NOT_CONFIRMED)
|
|
284
284
|
}
|
|
285
285
|
|
|
286
|
+
const now = new Date()
|
|
286
287
|
const refreshToken = this.createRefreshToken(userWithCustomData)
|
|
287
288
|
const refreshTokenHash = hashToken(refreshToken)
|
|
288
289
|
await authDb.collection(refreshTokensCollection).insertOne({
|
|
289
290
|
userId: authUser._id,
|
|
290
291
|
tokenHash: refreshTokenHash,
|
|
291
|
-
createdAt:
|
|
292
|
+
createdAt: now,
|
|
292
293
|
expiresAt: new Date(Date.now() + refreshTokenTtlMs),
|
|
293
294
|
revokedAt: null
|
|
294
295
|
})
|
|
296
|
+
await authDb.collection(authCollection!).updateOne(
|
|
297
|
+
{ _id: authUser._id },
|
|
298
|
+
{ $set: { lastLoginAt: now } }
|
|
299
|
+
)
|
|
295
300
|
|
|
296
301
|
return {
|
|
297
302
|
access_token: this.createAccessToken(userWithCustomData),
|
|
@@ -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' | 'LOGOUT'
|
|
27
|
+
operation_type?: 'CREATE' | 'DELETE' | 'LOGIN' | 'LOGOUT'
|
|
28
28
|
providers?: string[]
|
|
29
29
|
project: Record<string, unknown>
|
|
30
30
|
service_name: string
|
|
@@ -172,6 +172,7 @@ const handleCronTrigger = async ({
|
|
|
172
172
|
const mapOpInverse = {
|
|
173
173
|
CREATE: ['insert', 'update', 'replace'],
|
|
174
174
|
DELETE: ['delete'],
|
|
175
|
+
LOGIN: ['insert', 'update'],
|
|
175
176
|
LOGOUT: ['update'],
|
|
176
177
|
}
|
|
177
178
|
|
|
@@ -306,6 +307,8 @@ const handleAuthenticationTrigger = async ({
|
|
|
306
307
|
const isUpdate = operationType === 'update'
|
|
307
308
|
const isReplace = operationType === 'replace'
|
|
308
309
|
const isDelete = operationType === 'delete'
|
|
310
|
+
const isLoginInsert = isInsert && !!(fullDocument as Record<string, unknown> | null)?.lastLoginAt
|
|
311
|
+
const isLoginUpdate = isUpdate && !!updatedFields && 'lastLoginAt' in updatedFields
|
|
309
312
|
const isLogoutUpdate = isUpdate && !!updatedFields && 'lastLogoutAt' in updatedFields
|
|
310
313
|
|
|
311
314
|
let confirmedCandidate = false
|
|
@@ -397,6 +400,63 @@ const handleAuthenticationTrigger = async ({
|
|
|
397
400
|
return
|
|
398
401
|
}
|
|
399
402
|
|
|
403
|
+
if (operation_type === 'LOGIN') {
|
|
404
|
+
if (!isLoginInsert && !isLoginUpdate) {
|
|
405
|
+
return
|
|
406
|
+
}
|
|
407
|
+
let loginDocument = fullDocument ?? confirmedDocument
|
|
408
|
+
if (!loginDocument && documentKey?._id) {
|
|
409
|
+
loginDocument = await collection.findOne({
|
|
410
|
+
_id: documentKey._id
|
|
411
|
+
}) as Record<string, unknown> | null
|
|
412
|
+
}
|
|
413
|
+
if (!matchesProviderFilter(loginDocument, providerFilter)) {
|
|
414
|
+
return
|
|
415
|
+
}
|
|
416
|
+
const userData = buildUserData(loginDocument)
|
|
417
|
+
if (!userData) {
|
|
418
|
+
return
|
|
419
|
+
}
|
|
420
|
+
const op = {
|
|
421
|
+
operationType: 'LOGIN',
|
|
422
|
+
fullDocument,
|
|
423
|
+
fullDocumentBeforeChange,
|
|
424
|
+
documentKey,
|
|
425
|
+
updateDescription
|
|
426
|
+
}
|
|
427
|
+
try {
|
|
428
|
+
emitTriggerEvent({
|
|
429
|
+
status: 'fired',
|
|
430
|
+
triggerName,
|
|
431
|
+
triggerType,
|
|
432
|
+
functionName,
|
|
433
|
+
meta: { ...baseMeta, event: 'LOGIN' }
|
|
434
|
+
})
|
|
435
|
+
await GenerateContext({
|
|
436
|
+
args: [{ user: userData, ...op }],
|
|
437
|
+
app,
|
|
438
|
+
rules: StateManager.select("rules"),
|
|
439
|
+
user: {}, // TODO from currentUser ??
|
|
440
|
+
currentFunction: triggerHandler,
|
|
441
|
+
functionName,
|
|
442
|
+
functionsList,
|
|
443
|
+
services,
|
|
444
|
+
runAsSystem: true
|
|
445
|
+
})
|
|
446
|
+
} catch (error) {
|
|
447
|
+
emitTriggerEvent({
|
|
448
|
+
status: 'error',
|
|
449
|
+
triggerName,
|
|
450
|
+
triggerType,
|
|
451
|
+
functionName,
|
|
452
|
+
meta: { ...baseMeta, event: 'LOGIN' },
|
|
453
|
+
error
|
|
454
|
+
})
|
|
455
|
+
console.log("🚀 ~ handleAuthenticationTrigger ~ error:", error)
|
|
456
|
+
}
|
|
457
|
+
return
|
|
458
|
+
}
|
|
459
|
+
|
|
400
460
|
if (isDelete) {
|
|
401
461
|
if (isAutoTrigger || operation_type !== 'DELETE') {
|
|
402
462
|
return
|
|
@@ -4,7 +4,7 @@ import { Functions } from '../../features/functions/interface'
|
|
|
4
4
|
const mockServices = {
|
|
5
5
|
api: jest.fn().mockReturnValue({}),
|
|
6
6
|
aws: jest.fn().mockReturnValue({}),
|
|
7
|
-
'mongodb-atlas': jest.fn()
|
|
7
|
+
'mongodb-atlas': jest.fn((_app, options) => options ?? {})
|
|
8
8
|
} as any
|
|
9
9
|
|
|
10
10
|
describe('context.functions.execute compatibility', () => {
|
|
@@ -91,4 +91,30 @@ describe('context.functions.execute compatibility', () => {
|
|
|
91
91
|
|
|
92
92
|
expect(result).toBe(true)
|
|
93
93
|
})
|
|
94
|
+
|
|
95
|
+
it('propagates run_as_system to child functions executed through context.functions.execute', () => {
|
|
96
|
+
const functionsList = {
|
|
97
|
+
caller: {
|
|
98
|
+
run_as_system: true,
|
|
99
|
+
code: 'module.exports = function() { return context.functions.execute("target") }'
|
|
100
|
+
},
|
|
101
|
+
target: {
|
|
102
|
+
run_as_system: false,
|
|
103
|
+
code: 'module.exports = function() { return context.services.get("mongodb-atlas").run_as_system }'
|
|
104
|
+
}
|
|
105
|
+
} as Functions
|
|
106
|
+
|
|
107
|
+
const result = GenerateContextSync({
|
|
108
|
+
args: [],
|
|
109
|
+
app: {} as any,
|
|
110
|
+
rules: {} as any,
|
|
111
|
+
user: {} as any,
|
|
112
|
+
currentFunction: functionsList.caller,
|
|
113
|
+
functionsList,
|
|
114
|
+
services: mockServices,
|
|
115
|
+
functionName: 'caller'
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
expect(result).toBe(true)
|
|
119
|
+
})
|
|
94
120
|
})
|
|
@@ -79,7 +79,11 @@ describe('generateContextData', () => {
|
|
|
79
79
|
mockErrorLog.mockRestore()
|
|
80
80
|
|
|
81
81
|
context.functions.execute('test')
|
|
82
|
-
expect(GenerateContextSyncMock).
|
|
82
|
+
expect(GenerateContextSyncMock).toHaveBeenCalledWith(expect.objectContaining({
|
|
83
|
+
currentFunction,
|
|
84
|
+
functionName: 'test',
|
|
85
|
+
runAsSystem: currentFunction.run_as_system
|
|
86
|
+
}))
|
|
83
87
|
|
|
84
88
|
const token = jwt.sign(
|
|
85
89
|
{ sub: 'user', role: 'admin' },
|
|
@@ -205,16 +205,17 @@ export const generateContextData = ({
|
|
|
205
205
|
https: getService('api'),
|
|
206
206
|
functions: {
|
|
207
207
|
execute: (name: keyof typeof functionsList, ...args: Arguments) => {
|
|
208
|
-
const
|
|
208
|
+
const targetFunction = functionsList[name] as Function
|
|
209
209
|
return GenerateContextSync({
|
|
210
210
|
args,
|
|
211
211
|
app,
|
|
212
212
|
rules,
|
|
213
213
|
user,
|
|
214
|
-
currentFunction,
|
|
214
|
+
currentFunction: targetFunction,
|
|
215
215
|
functionName: String(name),
|
|
216
216
|
functionsList,
|
|
217
217
|
services,
|
|
218
|
+
runAsSystem: currentFunction.run_as_system,
|
|
218
219
|
deserializeArgs: false
|
|
219
220
|
})
|
|
220
221
|
}
|
|
@@ -189,8 +189,8 @@ export async function GenerateContext({
|
|
|
189
189
|
if (!currentFunction) return
|
|
190
190
|
|
|
191
191
|
const functionsQueue = StateManager.select("functionsQueue")
|
|
192
|
-
|
|
193
|
-
const functionToRun = { run_as_system:
|
|
192
|
+
const effectiveRunAsSystem = Boolean(runAsSystem || currentFunction.run_as_system)
|
|
193
|
+
const functionToRun = { ...currentFunction, run_as_system: effectiveRunAsSystem }
|
|
194
194
|
|
|
195
195
|
const run = async () => {
|
|
196
196
|
|
|
@@ -309,7 +309,8 @@ export function GenerateContextSync({
|
|
|
309
309
|
}: GenerateContextParams): unknown {
|
|
310
310
|
if (!currentFunction) return
|
|
311
311
|
|
|
312
|
-
const
|
|
312
|
+
const effectiveRunAsSystem = Boolean(runAsSystem || currentFunction.run_as_system)
|
|
313
|
+
const functionToRun = { ...currentFunction, run_as_system: effectiveRunAsSystem }
|
|
313
314
|
const contextData = generateContextData({
|
|
314
315
|
user,
|
|
315
316
|
services,
|