@friggframework/core 2.0.0-next.55 → 2.0.0-next.57

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.
@@ -53,7 +53,7 @@ class GetUserFromXFriggHeaders {
53
53
  );
54
54
  }
55
55
 
56
- // VALIDATION: If both IDs provided and both users exist, verify they match
56
+ // VALIDATION/AUTO-LINKING: If both IDs provided and both users exist, handle mismatch
57
57
  if (
58
58
  appUserId &&
59
59
  appOrgId &&
@@ -66,31 +66,57 @@ class GetUserFromXFriggHeaders {
66
66
  const expectedOrgId = organizationUserData.id?.toString();
67
67
 
68
68
  if (individualOrgId !== expectedOrgId) {
69
- throw Boom.badRequest(
70
- 'User ID mismatch: x-frigg-appUserId and x-frigg-appOrgId refer to different users. ' +
71
- 'Provide only one identifier or ensure they belong to the same user.'
69
+ // Default behavior: Auto-link disconnected users
70
+ // Opt-in strict mode: Throw error on mismatch
71
+ if (this.userConfig.strictUserValidation) {
72
+ throw Boom.badRequest(
73
+ 'User ID mismatch: x-frigg-appUserId and x-frigg-appOrgId refer to different users. ' +
74
+ 'Provide only one identifier or ensure they belong to the same user.'
75
+ );
76
+ }
77
+
78
+ // Auto-link the users
79
+ individualUserData = await this.userRepository.linkIndividualToOrganization(
80
+ individualUserData.id,
81
+ organizationUserData.id
72
82
  );
73
83
  }
74
84
  }
75
85
 
76
- // Auto-create user if not found
77
- if (!individualUserData && !organizationUserData) {
78
- if (appUserId) {
79
- individualUserData =
80
- await this.userRepository.createIndividualUser({
81
- appUserId,
82
- username: `app-user-${appUserId}`,
83
- email: `${appUserId}@app.local`,
84
- });
85
- } else {
86
- organizationUserData =
87
- await this.userRepository.createOrganizationUser({
88
- appOrgId,
89
- });
86
+ // Auto-create users independently if they don't exist and are required
87
+ if (
88
+ !individualUserData &&
89
+ appUserId &&
90
+ this.userConfig.individualUserRequired !== false
91
+ ) {
92
+ individualUserData =
93
+ await this.userRepository.createIndividualUser({
94
+ appUserId,
95
+ username: `app-user-${appUserId}`,
96
+ email: `${appUserId}@app.local`,
97
+ });
98
+ }
99
+
100
+ if (
101
+ !organizationUserData &&
102
+ appOrgId &&
103
+ this.userConfig.organizationUserRequired
104
+ ) {
105
+ organizationUserData =
106
+ await this.userRepository.createOrganizationUser({
107
+ appOrgId,
108
+ });
109
+
110
+ // Link individual user to newly created org user if individual exists
111
+ if (individualUserData && organizationUserData) {
112
+ individualUserData = await this.userRepository.linkIndividualToOrganization(
113
+ individualUserData.id,
114
+ organizationUserData.id
115
+ );
90
116
  }
91
117
  }
92
118
 
93
- return new User(
119
+ const user = new User(
94
120
  individualUserData,
95
121
  organizationUserData,
96
122
  this.userConfig.usePassword,
@@ -98,9 +124,9 @@ class GetUserFromXFriggHeaders {
98
124
  this.userConfig.individualUserRequired,
99
125
  this.userConfig.organizationUserRequired
100
126
  );
127
+
128
+ return user;
101
129
  }
102
130
  }
103
131
 
104
132
  module.exports = { GetUserFromXFriggHeaders };
105
-
106
-
package/user/user.js CHANGED
@@ -88,6 +88,38 @@ class User {
88
88
  getAppOrgId() {
89
89
  return this.organizationUser?.appOrgId || null;
90
90
  }
91
+
92
+ /**
93
+ * Checks if a given userId belongs to this user (either primary or linked).
94
+ * When primary is 'organization', entities owned by the linked individual user
95
+ * should still be accessible to the organization.
96
+ *
97
+ * @param {string|number} userId - The userId to check
98
+ * @returns {boolean} True if the userId belongs to this user or their linked user
99
+ */
100
+ ownsUserId(userId) {
101
+ const userIdStr = userId?.toString();
102
+ const primaryId = this.getPrimaryUser()?.id?.toString();
103
+ const individualId = this.individualUser?.id?.toString();
104
+ const organizationId = this.organizationUser?.id?.toString();
105
+
106
+ // Check if userId matches primary user
107
+ if (userIdStr === primaryId) {
108
+ return true;
109
+ }
110
+
111
+ // When primary is 'organization', also check linked individual user
112
+ if (this.config.primary === 'organization' && userIdStr === individualId) {
113
+ return true;
114
+ }
115
+
116
+ // When primary is 'individual', also check linked organization user if required
117
+ if (this.config.primary === 'individual' && this.config.organizationUserRequired && userIdStr === organizationId) {
118
+ return true;
119
+ }
120
+
121
+ return false;
122
+ }
91
123
  }
92
124
 
93
125
  module.exports = { User };