@flowerforce/flowerbase 1.10.0 → 1.10.1-beta.0

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,6 +1,14 @@
1
1
  import { mongodb } from '@fastify/mongodb';
2
- import { Arguments } from '../../auth/dtos';
2
+ import { Arguments, User } from '../../auth/dtos';
3
3
  import { GenerateContextDataParams } from './interface';
4
+ /** Realm-compatible system user for run_as_system execution with no authenticated caller. */
5
+ export declare const REALM_SYSTEM_USER: {
6
+ readonly type: "system";
7
+ readonly data: {};
8
+ readonly custom_data: {};
9
+ readonly identities: readonly [];
10
+ };
11
+ export declare const contextUserForRun: (user: User, runAsSystem: boolean) => User;
4
12
  type JwtUtils = {
5
13
  encode: (signingMethod: string, payload: unknown, secret: string | Buffer, customHeaderFields?: Record<string, unknown>) => string;
6
14
  decode: (jwtString: string, key: string | Buffer, returnHeader?: boolean, acceptedSigningMethods?: string[]) => unknown;
@@ -46,6 +54,7 @@ export declare const generateContextData: ({ user, services, app, rules, current
46
54
  action: string;
47
55
  };
48
56
  user: unknown;
57
+ runningAsSystem: () => boolean;
49
58
  environment: {
50
59
  tag: string | undefined;
51
60
  };
@@ -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;;;;;;;;;;;0BAoBmB,MAAM,GAAG,SAAS;2BACV,MAAM,GAAG,SAAS;;;;;;;;;uBAS1D,MAAM;;;;;;+BA5DU,MAAM,OAAO,QAAQ;;;;sCA1HrC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BAsGT,CAAC;iCAAa,CAAC;;;;;;;;;;;;;;;;;;;kCAtGP,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAsGT,CAAC;6BAAa,CAAC;;;;;;;;;;;;;;;;;;kCAtGP,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAsGT,CAAC;6BAAa,CAAC;;;;;;;;;;;;;;;4BAyFF,MAAM,OAAO,aAAa,WAAW,SAAS;;;CAkBrE,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;AAG1C,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAA;AAEjD,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AAEvD,6FAA6F;AAC7F,eAAO,MAAM,iBAAiB;;;;;CAKpB,CAAA;AAKV,eAAO,MAAM,iBAAiB,GAAI,MAAM,IAAI,EAAE,aAAa,OAAO,KAAG,IACR,CAAA;AAE7D,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;;;;;;;;;;;0BAoBmB,MAAM,GAAG,SAAS;2BACV,MAAM,GAAG,SAAS;;;;;;;;;;uBAU1D,MAAM;;;;;;+BA7DU,MAAM,OAAO,QAAQ;;;;sCAjJtD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8BAkHM,CAAC;iCAAa,CAAC;;;;;;;;;;;;;;;;;;;kCAlHtB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAkHM,CAAC;6BAAa,CAAC;;;;;;;;;;;;;;;;;;kCAlHtB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAkHM,CAAC;6BAAa,CAAC;;;;;;;;;;;;;;;4BAqGA,MAAM,OAAO,aAAa,WAAW,SAAS;;;CAkBrE,CAAA"}
@@ -33,10 +33,20 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.generateContextData = void 0;
36
+ exports.generateContextData = exports.contextUserForRun = exports.REALM_SYSTEM_USER = void 0;
37
37
  const mongodb_1 = require("@fastify/mongodb");
38
38
  const bson_1 = require("bson");
39
39
  const jwt = __importStar(require("jsonwebtoken"));
40
+ /** Realm-compatible system user for run_as_system execution with no authenticated caller. */
41
+ exports.REALM_SYSTEM_USER = {
42
+ type: 'system',
43
+ data: {},
44
+ custom_data: {},
45
+ identities: []
46
+ };
47
+ const isEmptyUser = (user) => user != null && typeof user === 'object' && !Array.isArray(user) && Object.keys(user).length === 0;
48
+ const contextUserForRun = (user, runAsSystem) => runAsSystem && isEmptyUser(user) ? exports.REALM_SYSTEM_USER : user;
49
+ exports.contextUserForRun = contextUserForRun;
40
50
  const normalizePayload = (payload) => {
41
51
  if (typeof payload !== 'string')
42
52
  return payload;
@@ -179,6 +189,7 @@ const generateContextData = ({ user, services, app, rules, currentFunction, func
179
189
  action: ''
180
190
  },
181
191
  user,
192
+ runningAsSystem: () => Boolean(currentFunction.run_as_system),
182
193
  environment: {
183
194
  tag: process.env.NODE_ENV
184
195
  },
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/context/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AA8RnD;;;;;;;;;;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,CA0BjC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/context/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AA8RnD;;;;;;;;;;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,CA4G1C;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,CA2BjC"}
@@ -238,10 +238,11 @@ function GenerateContext(_a) {
238
238
  const functionsQueue = state_1.StateManager.select("functionsQueue");
239
239
  const effectiveRunAsSystem = Boolean(runAsSystem || currentFunction.run_as_system);
240
240
  const functionToRun = Object.assign(Object.assign({}, currentFunction), { run_as_system: effectiveRunAsSystem });
241
+ const contextUser = (0, helpers_1.contextUserForRun)(user, effectiveRunAsSystem);
241
242
  const run = () => __awaiter(this, void 0, void 0, function* () {
242
243
  var _a;
243
244
  const contextData = (0, helpers_1.generateContextData)({
244
- user,
245
+ user: contextUser,
245
246
  services,
246
247
  app,
247
248
  rules,
@@ -315,8 +316,9 @@ function GenerateContextSync({ args, app, rules, user, currentFunction, function
315
316
  return;
316
317
  const effectiveRunAsSystem = Boolean(runAsSystem || currentFunction.run_as_system);
317
318
  const functionToRun = Object.assign(Object.assign({}, currentFunction), { run_as_system: effectiveRunAsSystem });
319
+ const contextUser = (0, helpers_1.contextUserForRun)(user, effectiveRunAsSystem);
318
320
  const contextData = (0, helpers_1.generateContextData)({
319
- user,
321
+ user: contextUser,
320
322
  services,
321
323
  app,
322
324
  rules,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowerforce/flowerbase",
3
- "version": "1.10.0",
3
+ "version": "1.10.1-beta.0",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -4,7 +4,7 @@ import { User } from '../../auth/dtos'
4
4
  import { Functions } from '../../features/functions/interface'
5
5
  import { Rules } from '../../features/rules/interface'
6
6
  import { services } from '../../services'
7
- import { generateContextData } from '../context/helpers'
7
+ import { contextUserForRun, generateContextData, REALM_SYSTEM_USER } from '../context/helpers'
8
8
 
9
9
  const originalEnv = process.env
10
10
 
@@ -113,4 +113,49 @@ describe('generateContextData', () => {
113
113
  const binaryObject = Binary.fromBase64Binary(base64, 0)
114
114
  expect(binaryObject).toBeInstanceOf(BSON.Binary)
115
115
  })
116
+
117
+ it('exposes Realm system user and runningAsSystem when run_as_system is enabled', () => {
118
+ const mockApp = Fastify()
119
+ const systemFunction = { ...currentFunction, run_as_system: true }
120
+ const { context } = generateContextData({
121
+ services,
122
+ app: mockApp,
123
+ functionsList: mockFunctions,
124
+ currentFunction: systemFunction,
125
+ GenerateContext: GenerateContextMock,
126
+ GenerateContextSync: GenerateContextSyncMock,
127
+ user: REALM_SYSTEM_USER,
128
+ rules: mockRules
129
+ })
130
+
131
+ expect(context.user).toEqual(REALM_SYSTEM_USER)
132
+ expect(context.runningAsSystem()).toBe(true)
133
+ })
134
+
135
+ it('runningAsSystem is false for regular function execution', () => {
136
+ const mockApp = Fastify()
137
+ const { context } = generateContextData({
138
+ services,
139
+ app: mockApp,
140
+ functionsList: mockFunctions,
141
+ currentFunction,
142
+ GenerateContext: GenerateContextMock,
143
+ GenerateContextSync: GenerateContextSyncMock,
144
+ user: { id: 'user-1', type: 'normal', data: {}, custom_data: {}, identities: [] },
145
+ rules: mockRules
146
+ })
147
+
148
+ expect(context.runningAsSystem()).toBe(false)
149
+ })
150
+ })
151
+
152
+ describe('contextUserForRun', () => {
153
+ it('returns Realm system user for empty user with run_as_system', () => {
154
+ expect(contextUserForRun({}, true)).toEqual(REALM_SYSTEM_USER)
155
+ })
156
+
157
+ it('returns the user unchanged when not running as system', () => {
158
+ const user = { id: 'user-1' }
159
+ expect(contextUserForRun(user, false)).toBe(user)
160
+ })
116
161
  })
@@ -1,10 +1,24 @@
1
1
  import { mongodb } from '@fastify/mongodb'
2
2
  import { EJSON } from 'bson'
3
3
  import * as jwt from 'jsonwebtoken'
4
- import { Arguments } from '../../auth/dtos'
4
+ import { Arguments, User } from '../../auth/dtos'
5
5
  import { Function } from '../../features/functions/interface'
6
6
  import { GenerateContextDataParams } from './interface'
7
7
 
8
+ /** Realm-compatible system user for run_as_system execution with no authenticated caller. */
9
+ export const REALM_SYSTEM_USER = {
10
+ type: 'system',
11
+ data: {},
12
+ custom_data: {},
13
+ identities: []
14
+ } as const
15
+
16
+ const isEmptyUser = (user: User) =>
17
+ user != null && typeof user === 'object' && !Array.isArray(user) && Object.keys(user).length === 0
18
+
19
+ export const contextUserForRun = (user: User, runAsSystem: boolean): User =>
20
+ runAsSystem && isEmptyUser(user) ? REALM_SYSTEM_USER : user
21
+
8
22
  type JwtUtils = {
9
23
  encode: (
10
24
  signingMethod: string,
@@ -207,6 +221,7 @@ export const generateContextData = ({
207
221
  action: ''
208
222
  },
209
223
  user,
224
+ runningAsSystem: () => Boolean(currentFunction.run_as_system),
210
225
  environment: {
211
226
  tag: process.env.NODE_ENV
212
227
  },
@@ -6,7 +6,7 @@ import vm from 'vm'
6
6
  import { EJSON } from 'bson'
7
7
  import { StateManager } from '../../state'
8
8
  import { Function as AppFunction } from '../../features/functions/interface'
9
- import { generateContextData } from './helpers'
9
+ import { contextUserForRun, generateContextData } from './helpers'
10
10
  import { GenerateContextParams } from './interface'
11
11
 
12
12
  const dynamicImport = new Function('specifier', 'return import(specifier)') as (
@@ -323,11 +323,12 @@ export async function GenerateContext({
323
323
  const functionsQueue = StateManager.select("functionsQueue")
324
324
  const effectiveRunAsSystem = Boolean(runAsSystem || currentFunction.run_as_system)
325
325
  const functionToRun = { ...currentFunction, run_as_system: effectiveRunAsSystem }
326
+ const contextUser = contextUserForRun(user, effectiveRunAsSystem)
326
327
 
327
328
  const run = async () => {
328
329
 
329
330
  const contextData = generateContextData({
330
- user,
331
+ user: contextUser,
331
332
  services,
332
333
  app,
333
334
  rules,
@@ -443,8 +444,9 @@ export function GenerateContextSync({
443
444
 
444
445
  const effectiveRunAsSystem = Boolean(runAsSystem || currentFunction.run_as_system)
445
446
  const functionToRun = { ...currentFunction, run_as_system: effectiveRunAsSystem }
447
+ const contextUser = contextUserForRun(user, effectiveRunAsSystem)
446
448
  const contextData = generateContextData({
447
- user,
449
+ user: contextUser,
448
450
  services,
449
451
  app,
450
452
  rules,