@flowerforce/flowerbase 1.6.1 → 1.6.2-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.
@@ -23,7 +23,7 @@ const utils_1 = require("../../utils");
23
23
  function anonUserController(app) {
24
24
  return __awaiter(this, void 0, void 0, function* () {
25
25
  const db = app.mongo.client.db(constants_1.DB_NAME);
26
- const { authCollection, refreshTokensCollection, providers } = constants_1.AUTH_CONFIG;
26
+ const { authCollection, refreshTokensCollection } = constants_1.AUTH_CONFIG;
27
27
  const refreshTokenTtlMs = constants_1.DEFAULT_CONFIG.REFRESH_TOKEN_TTL_DAYS * 24 * 60 * 60 * 1000;
28
28
  const anonUserTtlSeconds = constants_1.DEFAULT_CONFIG.ANON_USER_TTL_SECONDS;
29
29
  try {
@@ -37,8 +37,9 @@ function anonUserController(app) {
37
37
  }
38
38
  app.post(utils_1.AUTH_ENDPOINTS.LOGIN, function () {
39
39
  return __awaiter(this, void 0, void 0, function* () {
40
- const anonProvider = providers === null || providers === void 0 ? void 0 : providers['anon-user'];
41
- if (anonProvider === null || anonProvider === void 0 ? void 0 : anonProvider.disabled) {
40
+ var _a;
41
+ const anonProvider = (_a = constants_1.AUTH_CONFIG.authProviders) === null || _a === void 0 ? void 0 : _a['anon-user'];
42
+ if (!anonProvider || anonProvider.disabled) {
42
43
  throw new Error('Anonymous authentication disabled');
43
44
  }
44
45
  const now = new Date();
@@ -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;AASzC;;;;GAIG;AACH,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,eAAe,iBAgGlE"}
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;AASzC;;;;GAIG;AACH,wBAAsB,wBAAwB,CAAC,GAAG,EAAE,eAAe,iBAoGlE"}
@@ -39,8 +39,13 @@ function customFunctionController(app) {
39
39
  schema: schema_1.LOGIN_SCHEMA
40
40
  }, function (req, reply) {
41
41
  return __awaiter(this, void 0, void 0, function* () {
42
- const { providers } = constants_1.AUTH_CONFIG;
43
- const authFunctionName = providers["custom-function"].authFunctionName;
42
+ var _a, _b;
43
+ const customFunctionProvider = (_a = constants_1.AUTH_CONFIG.authProviders) === null || _a === void 0 ? void 0 : _a['custom-function'];
44
+ if (!customFunctionProvider || customFunctionProvider.disabled) {
45
+ throw new Error('Custom function authentication disabled');
46
+ }
47
+ const authFunctionName = (_b = customFunctionProvider
48
+ .config) === null || _b === void 0 ? void 0 : _b.authFunctionName;
44
49
  if (!authFunctionName || !functionsList[authFunctionName]) {
45
50
  throw new Error("Missing Auth Function");
46
51
  }
@@ -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,iBAqVjE"}
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,iBA8WjE"}
@@ -47,6 +47,7 @@ function localUserPassController(app) {
47
47
  const registerMaxAttempts = constants_1.DEFAULT_CONFIG.AUTH_REGISTER_MAX_ATTEMPTS;
48
48
  const resetMaxAttempts = constants_1.DEFAULT_CONFIG.AUTH_RESET_MAX_ATTEMPTS;
49
49
  const refreshTokenTtlMs = constants_1.DEFAULT_CONFIG.REFRESH_TOKEN_TTL_DAYS * 24 * 60 * 60 * 1000;
50
+ const resolveLocalUserpassProvider = () => { var _a; return (_a = constants_1.AUTH_CONFIG.authProviders) === null || _a === void 0 ? void 0 : _a['local-userpass']; };
50
51
  try {
51
52
  yield db.collection(resetPasswordCollection).createIndex({ createdAt: 1 }, { expireAfterSeconds: resetPasswordTtlSeconds });
52
53
  }
@@ -102,6 +103,10 @@ function localUserPassController(app) {
102
103
  app.post(utils_1.AUTH_ENDPOINTS.REGISTRATION, {
103
104
  schema: utils_1.REGISTRATION_SCHEMA
104
105
  }, (req, res) => __awaiter(this, void 0, void 0, function* () {
106
+ const localUserpassProvider = resolveLocalUserpassProvider();
107
+ if (!localUserpassProvider || localUserpassProvider.disabled) {
108
+ throw new Error('Local userpass authentication disabled');
109
+ }
105
110
  const key = `register:${req.ip}`;
106
111
  if (isRateLimited(key, registerMaxAttempts, rateLimitWindowMs)) {
107
112
  res.status(429).send({ message: 'Too many requests' });
@@ -141,6 +146,10 @@ function localUserPassController(app) {
141
146
  app.post(utils_1.AUTH_ENDPOINTS.CONFIRM, {
142
147
  schema: utils_1.CONFIRM_USER_SCHEMA
143
148
  }, (req, res) => __awaiter(this, void 0, void 0, function* () {
149
+ const localUserpassProvider = resolveLocalUserpassProvider();
150
+ if (!localUserpassProvider || localUserpassProvider.disabled) {
151
+ throw new Error('Local userpass authentication disabled');
152
+ }
144
153
  const key = `confirm:${req.ip}`;
145
154
  if (isRateLimited(key, resetMaxAttempts, rateLimitWindowMs)) {
146
155
  res.status(429).send({ message: 'Too many requests' });
@@ -174,6 +183,10 @@ function localUserPassController(app) {
174
183
  schema: utils_1.LOGIN_SCHEMA
175
184
  }, function (req, res) {
176
185
  return __awaiter(this, void 0, void 0, function* () {
186
+ const localUserpassProvider = resolveLocalUserpassProvider();
187
+ if (!localUserpassProvider || localUserpassProvider.disabled) {
188
+ throw new Error('Local userpass authentication disabled');
189
+ }
177
190
  const key = `login:${req.ip}`;
178
191
  if (isRateLimited(key, loginMaxAttempts, rateLimitWindowMs)) {
179
192
  res.status(429).send({ message: 'Too many requests' });
@@ -227,6 +240,10 @@ function localUserPassController(app) {
227
240
  schema: utils_1.RESET_SEND_SCHEMA
228
241
  }, function (req, res) {
229
242
  return __awaiter(this, void 0, void 0, function* () {
243
+ const localUserpassProvider = resolveLocalUserpassProvider();
244
+ if (!localUserpassProvider || localUserpassProvider.disabled) {
245
+ throw new Error('Local userpass authentication disabled');
246
+ }
230
247
  const key = `reset:${req.ip}`;
231
248
  if (isRateLimited(key, resetMaxAttempts, rateLimitWindowMs)) {
232
249
  res.status(429);
@@ -243,6 +260,10 @@ function localUserPassController(app) {
243
260
  schema: utils_1.RESET_CALL_SCHEMA
244
261
  }, function (req, res) {
245
262
  return __awaiter(this, void 0, void 0, function* () {
263
+ const localUserpassProvider = resolveLocalUserpassProvider();
264
+ if (!localUserpassProvider || localUserpassProvider.disabled) {
265
+ throw new Error('Local userpass authentication disabled');
266
+ }
246
267
  const key = `reset:${req.ip}`;
247
268
  if (isRateLimited(key, resetMaxAttempts, rateLimitWindowMs)) {
248
269
  res.status(429);
@@ -266,6 +287,10 @@ function localUserPassController(app) {
266
287
  schema: utils_1.CONFIRM_RESET_SCHEMA
267
288
  }, function (req, res) {
268
289
  return __awaiter(this, void 0, void 0, function* () {
290
+ const localUserpassProvider = resolveLocalUserpassProvider();
291
+ if (!localUserpassProvider || localUserpassProvider.disabled) {
292
+ throw new Error('Local userpass authentication disabled');
293
+ }
269
294
  const key = `reset-confirm:${req.ip}`;
270
295
  if (isRateLimited(key, resetMaxAttempts, rateLimitWindowMs)) {
271
296
  res.status(429);
@@ -149,7 +149,7 @@ const loadAuthConfig = () => {
149
149
  'anon-user': {
150
150
  name: 'anon-user',
151
151
  type: 'anon-user',
152
- disabled: false
152
+ disabled: true
153
153
  }
154
154
  };
155
155
  }
@@ -24,6 +24,10 @@ export declare const DEFAULT_CONFIG: {
24
24
  export declare const API_VERSION: string;
25
25
  export declare const HTTPS_SCHEMA: string;
26
26
  export declare const DB_NAME: string;
27
+ type AuthProviders = Record<string, {
28
+ disabled?: boolean;
29
+ config?: unknown;
30
+ }>;
27
31
  export declare const AUTH_CONFIG: {
28
32
  authCollection: string;
29
33
  userCollection: string;
@@ -31,6 +35,7 @@ export declare const AUTH_CONFIG: {
31
35
  refreshTokensCollection: string;
32
36
  resetPasswordConfig: import("./auth/utils").Config;
33
37
  localUserpassConfig: import("./auth/utils").Config;
38
+ authProviders: AuthProviders;
34
39
  user_id_field: string;
35
40
  on_user_creation_function_name: string;
36
41
  providers: {
@@ -44,4 +49,5 @@ export declare const S3_CONFIG: {
44
49
  ACCESS_KEY_ID: string | undefined;
45
50
  SECRET_ACCESS_KEY: string | undefined;
46
51
  };
52
+ export {};
47
53
  //# sourceMappingURL=constants.d.ts.map
@@ -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;;;;;;;;;;;;;;;;;;;iBAmBsB,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;;;;;;;;;;;;;;;CAavB,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;;;;;;;;;;;;;;;;;;;iBAmBsB,eAAe,EAAE;;CAEjE,CAAA;AACD,eAAO,MAAM,WAAW,QAA8C,CAAA;AACtE,eAAO,MAAM,YAAY,QAA8B,CAAA;AACvD,eAAO,MAAM,OAAO,QAAgB,CAAA;AAEpC,KAAK,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAAA;AAE7E,eAAO,MAAM,WAAW;;;;;;;mBAOqB,aAAa;;;;;;;;;CAOzD,CAAA;AAID,eAAO,MAAM,SAAS;;;CAGrB,CAAA"}
package/dist/constants.js CHANGED
@@ -49,6 +49,7 @@ exports.AUTH_CONFIG = {
49
49
  refreshTokensCollection: 'auth_refresh_tokens',
50
50
  resetPasswordConfig: (_a = configuration['local-userpass']) === null || _a === void 0 ? void 0 : _a.config,
51
51
  localUserpassConfig: (_b = configuration['local-userpass']) === null || _b === void 0 ? void 0 : _b.config,
52
+ authProviders: configuration,
52
53
  user_id_field,
53
54
  on_user_creation_function_name,
54
55
  providers: {
@@ -23,6 +23,7 @@ type Config = {
23
23
  match: Record<string, unknown>;
24
24
  operation_types: string[];
25
25
  operation_type?: 'CREATE' | 'DELETE' | 'LOGOUT';
26
+ providers?: string[];
26
27
  project: Record<string, unknown>;
27
28
  service_name: string;
28
29
  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,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
+ {"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,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;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;AAuaD,eAAO,MAAM,gBAAgB;0EAnZ1B,aAAa;yEAwVb,aAAa;+EAtSb,aAAa;CAqWf,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;AAyeD,eAAO,MAAM,gBAAgB;0EArd1B,aAAa;yEA0Zb,aAAa;+EArUb,aAAa;CAoYf,CAAA"}
@@ -123,6 +123,38 @@ const mapOpInverse = {
123
123
  LOGOUT: ['update'],
124
124
  };
125
125
  const normalizeOperationTypes = (operationTypes = []) => operationTypes.map((op) => op.toLowerCase());
126
+ const normalizeProviders = (providers = []) => providers
127
+ .map((provider) => (typeof provider === 'string' ? provider.trim().toLowerCase() : ''))
128
+ .filter((provider) => provider.length);
129
+ const extractProvidersFromDocument = (document) => {
130
+ if (!document)
131
+ return [];
132
+ const providers = [];
133
+ const identities = document.identities;
134
+ if (Array.isArray(identities)) {
135
+ for (const identity of identities) {
136
+ if (!identity || typeof identity !== 'object')
137
+ continue;
138
+ const providerType = identity.provider_type;
139
+ if (typeof providerType === 'string') {
140
+ providers.push(providerType.toLowerCase());
141
+ }
142
+ }
143
+ }
144
+ const rootProviderType = document.provider_type;
145
+ if (typeof rootProviderType === 'string') {
146
+ providers.push(rootProviderType.toLowerCase());
147
+ }
148
+ return providers;
149
+ };
150
+ const matchesProviderFilter = (document, providerFilter) => {
151
+ if (!providerFilter.length)
152
+ return true;
153
+ const documentProviders = extractProvidersFromDocument(document);
154
+ if (!documentProviders.length)
155
+ return false;
156
+ return documentProviders.some((provider) => providerFilter.includes(provider));
157
+ };
126
158
  const resolveDocumentOptions = ({ requestFullDocument, requestFullDocumentBeforeChange, normalizedOperations }) => {
127
159
  const includesUpdateOrReplace = normalizedOperations.some((op) => op === 'update' || op === 'replace');
128
160
  const fullDocument = (() => {
@@ -134,9 +166,10 @@ const resolveDocumentOptions = ({ requestFullDocument, requestFullDocumentBefore
134
166
  return { fullDocument, fullDocumentBeforeChange };
135
167
  };
136
168
  const handleAuthenticationTrigger = (_a) => __awaiter(void 0, [_a], void 0, function* ({ config, triggerHandler, functionsList, services, app }) {
137
- var _b;
169
+ var _b, _c;
138
170
  const { database, isAutoTrigger, operation_types = [], operation_type } = config;
139
- const authCollection = (_b = constants_1.AUTH_CONFIG.authCollection) !== null && _b !== void 0 ? _b : 'auth_users';
171
+ const providerFilter = normalizeProviders((_b = config.providers) !== null && _b !== void 0 ? _b : []);
172
+ const authCollection = (_c = constants_1.AUTH_CONFIG.authCollection) !== null && _c !== void 0 ? _c : 'auth_users';
140
173
  const collection = app.mongo.client.db(database || constants_1.DB_NAME).collection(authCollection);
141
174
  const operationCandidates = operation_type ? mapOpInverse[operation_type] : operation_types;
142
175
  const normalizedOps = normalizeOperationTypes(operationCandidates);
@@ -216,6 +249,9 @@ const handleAuthenticationTrigger = (_a) => __awaiter(void 0, [_a], void 0, func
216
249
  _id: documentKey._id
217
250
  }));
218
251
  }
252
+ if (!matchesProviderFilter(logoutDocument, providerFilter)) {
253
+ return;
254
+ }
219
255
  const userData = buildUserData(logoutDocument);
220
256
  if (!userData) {
221
257
  return;
@@ -248,7 +284,11 @@ const handleAuthenticationTrigger = (_a) => __awaiter(void 0, [_a], void 0, func
248
284
  if (isAutoTrigger || operation_type !== 'DELETE') {
249
285
  return;
250
286
  }
251
- const userData = buildUserData(fullDocumentBeforeChange !== null && fullDocumentBeforeChange !== void 0 ? fullDocumentBeforeChange : confirmedDocument);
287
+ const deleteDocument = fullDocumentBeforeChange !== null && fullDocumentBeforeChange !== void 0 ? fullDocumentBeforeChange : confirmedDocument;
288
+ if (!matchesProviderFilter(deleteDocument, providerFilter)) {
289
+ return;
290
+ }
291
+ const userData = buildUserData(deleteDocument);
252
292
  if (!userData) {
253
293
  return;
254
294
  }
@@ -277,7 +317,16 @@ const handleAuthenticationTrigger = (_a) => __awaiter(void 0, [_a], void 0, func
277
317
  return;
278
318
  }
279
319
  if (isReplace) {
280
- const userData = buildUserData(confirmedDocument);
320
+ let replaceDocument = confirmedDocument;
321
+ if (!replaceDocument && providerFilter.length && (documentKey === null || documentKey === void 0 ? void 0 : documentKey._id)) {
322
+ replaceDocument = (yield collection.findOne({
323
+ _id: documentKey._id
324
+ }));
325
+ }
326
+ if (!matchesProviderFilter(replaceDocument, providerFilter)) {
327
+ return;
328
+ }
329
+ const userData = buildUserData(replaceDocument);
281
330
  if (!userData) {
282
331
  return;
283
332
  }
@@ -323,6 +372,16 @@ const handleAuthenticationTrigger = (_a) => __awaiter(void 0, [_a], void 0, func
323
372
  if (!confirmedCandidate) {
324
373
  return;
325
374
  }
375
+ let candidateDocument = confirmedDocument;
376
+ if (!candidateDocument && providerFilter.length && (documentKey === null || documentKey === void 0 ? void 0 : documentKey._id)) {
377
+ candidateDocument = (yield collection.findOne({
378
+ _id: documentKey._id
379
+ }));
380
+ confirmedDocument = candidateDocument !== null && candidateDocument !== void 0 ? candidateDocument : confirmedDocument;
381
+ }
382
+ if (!matchesProviderFilter(candidateDocument, providerFilter)) {
383
+ return;
384
+ }
326
385
  const updateResult = yield collection.findOneAndUpdate({
327
386
  _id: documentKey._id,
328
387
  status: 'confirmed',
@@ -339,6 +398,9 @@ const handleAuthenticationTrigger = (_a) => __awaiter(void 0, [_a], void 0, func
339
398
  return;
340
399
  }
341
400
  delete document.password;
401
+ if (!matchesProviderFilter(document, providerFilter)) {
402
+ return;
403
+ }
342
404
  const userData = buildUserData(document);
343
405
  if (!userData) {
344
406
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowerforce/flowerbase",
3
- "version": "1.6.1",
3
+ "version": "1.6.2-beta.0",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -13,7 +13,7 @@ import { LoginDto } from './dtos'
13
13
  */
14
14
  export async function anonUserController(app: FastifyInstance) {
15
15
  const db = app.mongo.client.db(DB_NAME)
16
- const { authCollection, refreshTokensCollection, providers } = AUTH_CONFIG
16
+ const { authCollection, refreshTokensCollection } = AUTH_CONFIG
17
17
  const refreshTokenTtlMs = DEFAULT_CONFIG.REFRESH_TOKEN_TTL_DAYS * 24 * 60 * 60 * 1000
18
18
  const anonUserTtlSeconds = DEFAULT_CONFIG.ANON_USER_TTL_SECONDS
19
19
 
@@ -32,8 +32,8 @@ export async function anonUserController(app: FastifyInstance) {
32
32
  app.post<LoginDto>(
33
33
  AUTH_ENDPOINTS.LOGIN,
34
34
  async function () {
35
- const anonProvider = providers?.['anon-user']
36
- if (anonProvider?.disabled) {
35
+ const anonProvider = AUTH_CONFIG.authProviders?.['anon-user']
36
+ if (!anonProvider || anonProvider.disabled) {
37
37
  throw new Error('Anonymous authentication disabled')
38
38
  }
39
39
 
@@ -33,8 +33,12 @@ export async function customFunctionController(app: FastifyInstance) {
33
33
  schema: LOGIN_SCHEMA
34
34
  },
35
35
  async function (req, reply) {
36
- const { providers } = AUTH_CONFIG
37
- const authFunctionName = providers["custom-function"].authFunctionName
36
+ const customFunctionProvider = AUTH_CONFIG.authProviders?.['custom-function']
37
+ if (!customFunctionProvider || customFunctionProvider.disabled) {
38
+ throw new Error('Custom function authentication disabled')
39
+ }
40
+ const authFunctionName = (customFunctionProvider as { config?: { authFunctionName?: string } })
41
+ .config?.authFunctionName
38
42
 
39
43
  if (!authFunctionName || !functionsList[authFunctionName]) {
40
44
  throw new Error("Missing Auth Function")
@@ -51,6 +51,7 @@ export async function localUserPassController(app: FastifyInstance) {
51
51
  const registerMaxAttempts = DEFAULT_CONFIG.AUTH_REGISTER_MAX_ATTEMPTS
52
52
  const resetMaxAttempts = DEFAULT_CONFIG.AUTH_RESET_MAX_ATTEMPTS
53
53
  const refreshTokenTtlMs = DEFAULT_CONFIG.REFRESH_TOKEN_TTL_DAYS * 24 * 60 * 60 * 1000
54
+ const resolveLocalUserpassProvider = () => AUTH_CONFIG.authProviders?.['local-userpass']
54
55
 
55
56
  try {
56
57
  await db.collection(resetPasswordCollection).createIndex(
@@ -132,6 +133,10 @@ export async function localUserPassController(app: FastifyInstance) {
132
133
  schema: REGISTRATION_SCHEMA
133
134
  },
134
135
  async (req, res) => {
136
+ const localUserpassProvider = resolveLocalUserpassProvider()
137
+ if (!localUserpassProvider || localUserpassProvider.disabled) {
138
+ throw new Error('Local userpass authentication disabled')
139
+ }
135
140
  const key = `register:${req.ip}`
136
141
  if (isRateLimited(key, registerMaxAttempts, rateLimitWindowMs)) {
137
142
  res.status(429).send({ message: 'Too many requests' })
@@ -178,6 +183,10 @@ export async function localUserPassController(app: FastifyInstance) {
178
183
  schema: CONFIRM_USER_SCHEMA
179
184
  },
180
185
  async (req, res) => {
186
+ const localUserpassProvider = resolveLocalUserpassProvider()
187
+ if (!localUserpassProvider || localUserpassProvider.disabled) {
188
+ throw new Error('Local userpass authentication disabled')
189
+ }
181
190
  const key = `confirm:${req.ip}`
182
191
  if (isRateLimited(key, resetMaxAttempts, rateLimitWindowMs)) {
183
192
  res.status(429).send({ message: 'Too many requests' })
@@ -222,6 +231,10 @@ export async function localUserPassController(app: FastifyInstance) {
222
231
  schema: LOGIN_SCHEMA
223
232
  },
224
233
  async function (req, res) {
234
+ const localUserpassProvider = resolveLocalUserpassProvider()
235
+ if (!localUserpassProvider || localUserpassProvider.disabled) {
236
+ throw new Error('Local userpass authentication disabled')
237
+ }
225
238
  const key = `login:${req.ip}`
226
239
  if (isRateLimited(key, loginMaxAttempts, rateLimitWindowMs)) {
227
240
  res.status(429).send({ message: 'Too many requests' })
@@ -295,6 +308,10 @@ export async function localUserPassController(app: FastifyInstance) {
295
308
  schema: RESET_SEND_SCHEMA
296
309
  },
297
310
  async function (req, res) {
311
+ const localUserpassProvider = resolveLocalUserpassProvider()
312
+ if (!localUserpassProvider || localUserpassProvider.disabled) {
313
+ throw new Error('Local userpass authentication disabled')
314
+ }
298
315
  const key = `reset:${req.ip}`
299
316
  if (isRateLimited(key, resetMaxAttempts, rateLimitWindowMs)) {
300
317
  res.status(429)
@@ -314,6 +331,10 @@ export async function localUserPassController(app: FastifyInstance) {
314
331
  schema: RESET_CALL_SCHEMA
315
332
  },
316
333
  async function (req, res) {
334
+ const localUserpassProvider = resolveLocalUserpassProvider()
335
+ if (!localUserpassProvider || localUserpassProvider.disabled) {
336
+ throw new Error('Local userpass authentication disabled')
337
+ }
317
338
  const key = `reset:${req.ip}`
318
339
  if (isRateLimited(key, resetMaxAttempts, rateLimitWindowMs)) {
319
340
  res.status(429)
@@ -344,6 +365,10 @@ export async function localUserPassController(app: FastifyInstance) {
344
365
  schema: CONFIRM_RESET_SCHEMA
345
366
  },
346
367
  async function (req, res) {
368
+ const localUserpassProvider = resolveLocalUserpassProvider()
369
+ if (!localUserpassProvider || localUserpassProvider.disabled) {
370
+ throw new Error('Local userpass authentication disabled')
371
+ }
347
372
  const key = `reset-confirm:${req.ip}`
348
373
  if (isRateLimited(key, resetMaxAttempts, rateLimitWindowMs)) {
349
374
  res.status(429)
package/src/auth/utils.ts CHANGED
@@ -208,7 +208,7 @@ export const loadAuthConfig = (): AuthConfig => {
208
208
  'anon-user': {
209
209
  name: 'anon-user',
210
210
  type: 'anon-user',
211
- disabled: false
211
+ disabled: true
212
212
  }
213
213
  }
214
214
  }
package/src/constants.ts CHANGED
@@ -35,6 +35,7 @@ export const API_VERSION = `/api/client/${DEFAULT_CONFIG.API_VERSION}`
35
35
  export const HTTPS_SCHEMA = DEFAULT_CONFIG.HTTPS_SCHEMA
36
36
  export const DB_NAME = database_name
37
37
 
38
+ type AuthProviders = Record<string, { disabled?: boolean; config?: unknown }>
38
39
  // TODO spostare nell'oggetto providers anche le altre configurazioni
39
40
  export const AUTH_CONFIG = {
40
41
  authCollection: auth_collection,
@@ -43,6 +44,7 @@ export const AUTH_CONFIG = {
43
44
  refreshTokensCollection: 'auth_refresh_tokens',
44
45
  resetPasswordConfig: configuration['local-userpass']?.config,
45
46
  localUserpassConfig: configuration['local-userpass']?.config,
47
+ authProviders: configuration as unknown as AuthProviders,
46
48
  user_id_field,
47
49
  on_user_creation_function_name,
48
50
  providers: {
@@ -25,6 +25,7 @@ type Config = {
25
25
  match: Record<string, unknown>
26
26
  operation_types: string[]
27
27
  operation_type?: 'CREATE' | 'DELETE' | 'LOGOUT'
28
+ providers?: string[]
28
29
  project: Record<string, unknown>
29
30
  service_name: string
30
31
  skip_catchup_events: boolean
@@ -112,6 +112,41 @@ const mapOpInverse = {
112
112
  const normalizeOperationTypes = (operationTypes: string[] = []) =>
113
113
  operationTypes.map((op) => op.toLowerCase())
114
114
 
115
+ const normalizeProviders = (providers: string[] = []) =>
116
+ providers
117
+ .map((provider) => (typeof provider === 'string' ? provider.trim().toLowerCase() : ''))
118
+ .filter((provider) => provider.length)
119
+
120
+ const extractProvidersFromDocument = (document?: Record<string, unknown> | null) => {
121
+ if (!document) return []
122
+ const providers: string[] = []
123
+ const identities = (document as { identities?: unknown }).identities
124
+ if (Array.isArray(identities)) {
125
+ for (const identity of identities) {
126
+ if (!identity || typeof identity !== 'object') continue
127
+ const providerType = (identity as { provider_type?: unknown }).provider_type
128
+ if (typeof providerType === 'string') {
129
+ providers.push(providerType.toLowerCase())
130
+ }
131
+ }
132
+ }
133
+ const rootProviderType = (document as { provider_type?: unknown }).provider_type
134
+ if (typeof rootProviderType === 'string') {
135
+ providers.push(rootProviderType.toLowerCase())
136
+ }
137
+ return providers
138
+ }
139
+
140
+ const matchesProviderFilter = (
141
+ document: Record<string, unknown> | null | undefined,
142
+ providerFilter: string[]
143
+ ) => {
144
+ if (!providerFilter.length) return true
145
+ const documentProviders = extractProvidersFromDocument(document)
146
+ if (!documentProviders.length) return false
147
+ return documentProviders.some((provider) => providerFilter.includes(provider))
148
+ }
149
+
115
150
  const resolveDocumentOptions = ({
116
151
  requestFullDocument,
117
152
  requestFullDocumentBeforeChange,
@@ -140,6 +175,7 @@ const handleAuthenticationTrigger = async ({
140
175
  app
141
176
  }: HandlerParams) => {
142
177
  const { database, isAutoTrigger, operation_types = [], operation_type } = config
178
+ const providerFilter = normalizeProviders(config.providers ?? [])
143
179
  const authCollection = AUTH_CONFIG.authCollection ?? 'auth_users'
144
180
  const collection = app.mongo.client.db(database || DB_NAME).collection(authCollection)
145
181
  const operationCandidates = operation_type ? mapOpInverse[operation_type] : operation_types
@@ -238,6 +274,9 @@ const handleAuthenticationTrigger = async ({
238
274
  _id: documentKey._id
239
275
  }) as Record<string, unknown> | null
240
276
  }
277
+ if (!matchesProviderFilter(logoutDocument, providerFilter)) {
278
+ return
279
+ }
241
280
  const userData = buildUserData(logoutDocument)
242
281
  if (!userData) {
243
282
  return
@@ -270,7 +309,11 @@ const handleAuthenticationTrigger = async ({
270
309
  if (isAutoTrigger || operation_type !== 'DELETE') {
271
310
  return
272
311
  }
273
- const userData = buildUserData(fullDocumentBeforeChange ?? confirmedDocument)
312
+ const deleteDocument = fullDocumentBeforeChange ?? confirmedDocument
313
+ if (!matchesProviderFilter(deleteDocument, providerFilter)) {
314
+ return
315
+ }
316
+ const userData = buildUserData(deleteDocument)
274
317
  if (!userData) {
275
318
  return
276
319
  }
@@ -299,7 +342,16 @@ const handleAuthenticationTrigger = async ({
299
342
  }
300
343
 
301
344
  if (isReplace) {
302
- const userData = buildUserData(confirmedDocument)
345
+ let replaceDocument = confirmedDocument
346
+ if (!replaceDocument && providerFilter.length && documentKey?._id) {
347
+ replaceDocument = await collection.findOne({
348
+ _id: documentKey._id
349
+ }) as Record<string, unknown> | null
350
+ }
351
+ if (!matchesProviderFilter(replaceDocument, providerFilter)) {
352
+ return
353
+ }
354
+ const userData = buildUserData(replaceDocument)
303
355
  if (!userData) {
304
356
  return
305
357
  }
@@ -347,6 +399,17 @@ const handleAuthenticationTrigger = async ({
347
399
  return
348
400
  }
349
401
 
402
+ let candidateDocument = confirmedDocument
403
+ if (!candidateDocument && providerFilter.length && documentKey?._id) {
404
+ candidateDocument = await collection.findOne({
405
+ _id: documentKey._id
406
+ }) as Record<string, unknown> | null
407
+ confirmedDocument = candidateDocument ?? confirmedDocument
408
+ }
409
+ if (!matchesProviderFilter(candidateDocument, providerFilter)) {
410
+ return
411
+ }
412
+
350
413
  const updateResult = await collection.findOneAndUpdate(
351
414
  {
352
415
  _id: documentKey._id,
@@ -371,6 +434,9 @@ const handleAuthenticationTrigger = async ({
371
434
 
372
435
  delete (document as { password?: unknown }).password
373
436
 
437
+ if (!matchesProviderFilter(document, providerFilter)) {
438
+ return
439
+ }
374
440
  const userData = buildUserData(document)
375
441
  if (!userData) {
376
442
  return